<rss version="2.0">
  <channel>
    <title>Work on Ben McCormick</title>
    <link>https://benmccormick.org/categories/work/</link>
    <description></description>
    
    <language>en</language>
    
    <lastBuildDate>Fri, 22 Aug 2025 21:09:00 -0400</lastBuildDate>
    
    <item>
      <title>Coding is deciding</title>
      <link>https://benmccormick.org/2025/08/22/coding-is-deciding.html</link>
      <pubDate>Fri, 22 Aug 2025 21:09:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2025/08/22/coding-is-deciding.html</guid>
      <description>&lt;p&gt;We often talk about computer programs purely as collections of “code”.  Lately I’ve been thinking about it a bit differently: a computer program is the encoding of a huge series of nested decisions, made intentionally or otherwise. &lt;/p&gt;
&lt;p&gt;Let’s say we’ve decided to build a calculator app.  That overall goal is the first decision, but there are many more decisions nested underneath it.  &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;What features does our calculator app need? (Just basic arithmetic or are we buliding a graphing calculator?)&lt;/li&gt;
&lt;li&gt;What platform are we building for? (web, mobile, desktop, VR?)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Once we know generally what we’re trying to do, there’s still a bunch of fundamental decisions to be made before we write any code&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Is this a client only app or is there a server component?&lt;/li&gt;
&lt;li&gt;What framework should we use?&lt;/li&gt;
&lt;li&gt;How will the app be hosted and distributed?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Then once we start actually writing code, we find even more nested decisions.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;How are we going to structure our files?&lt;/li&gt;
&lt;li&gt;How will we break functionality up into components, classes and/or functions?&lt;/li&gt;
&lt;li&gt;Is this a single file, a single app, or some sort of distributed system?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And then even within a given class we nest even more decisions&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;What functionality should the class have?&lt;/li&gt;
&lt;li&gt;What is the high level logic of each function?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And then we come down to the lowest level of decisions&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;What syntax will we use for that? (For example: for loops or iterators to run through a list)&lt;/li&gt;
&lt;li&gt;Will we use a library or write some functionality from scratch?&lt;/li&gt;
&lt;li&gt;Tabs or spaces?  Single quotes or double quotes?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We can think of these as functional, infrastructure, architecture, logical and syntax level decisions.&lt;/p&gt;
&lt;p&gt;&lt;img title=&#34;base.png&#34; src=&#34;https://cdn.uploads.micro.blog/92198/2025/27128d4a6e.png&#34; alt=&#34;&#34; width=&#34;487&#34; height=&#34;600&#34; border=&#34;0&#34;&gt;&lt;/p&gt;
&lt;p&gt;The history of computing has mostly involved changing which of those decisions a software developer needs to make as tools have changed.  Many of those changes have removed the need to make decisions in favor of a generally acceptable standard implementation.  The vast majority of programmers no longer worry about the details of the bytecode or assembly definitions of programs — those have been standardized by higher level languages.  Most modern languages also remove or significantly reduce decision making around memory management, cloud platforms reduce&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; the decisions many devs need to make around infrastructure for their apps, and API frameworks like Django or Ruby on Rails reduce the decisions somebody needs to make about how to structure their API code.  &lt;/p&gt;
&lt;p&gt;Each of these abstractions have allowed developers to focus more on the decisions around what their program should do and less on the implementation details of how it does it.  They’re also all leaky abstractions to varying degrees, and there are times and situations where a developer will need to go without or work around the standard tool to make a different decision.  &lt;/p&gt;
&lt;p&gt;Applying this model to think about LLM based coding tools, it’s useful to talk about the use of LLM in terms of what decisions we’re making vs offloading to the coding tool. LLMs are essentially tools for replacing decisions that you might have had to make while generating text with a reasonable standardized option.  However the way we use them can lead to different sets of decisions being made by the tools.&lt;/p&gt;
&lt;h4&gt;Vibe Coding&lt;/h4&gt;
&lt;p&gt;Vibe coding, the buzzword of the year in tech, is commonly understood to mean that you’re creating an application solely through prompting and iterating based on the observed output without reading the code.  This is effectively choosing to make decisions at the functional level (and maybe the infra level) and let AI handle the rest.&lt;/p&gt;
&lt;p&gt;&lt;img title=&#34;vibe-coding.png&#34; src=&#34;https://cdn.uploads.micro.blog/92198/2025/vibe-coding.png&#34; alt=&#34;Vibe coding.&#34; width=&#34;487&#34; height=&#34;600&#34; border=&#34;0&#34;&gt;&lt;/p&gt;
&lt;h4&gt;Tab Complete&lt;/h4&gt;
&lt;p&gt;We can contrast this to a tab complete interface like those provided by Github Copilot or Cursor, where an IDE will offer to insert a chunk of code based on context.  Here AI is mostly deciding on syntax, with more ambitious implementations like Cursor possibly moving up to the logical level&lt;/p&gt;
&lt;p&gt;&lt;img title=&#34;tab-complete.png&#34; src=&#34;https://cdn.uploads.micro.blog/92198/2025/tab-complete.png&#34; alt=&#34;Tab complete.&#34; width=&#34;487&#34; height=&#34;600&#34; border=&#34;0&#34;&gt;&lt;/p&gt;
&lt;h4&gt;Feature Development With Agents&lt;/h4&gt;
&lt;p&gt;There’s a lot of room between these 2 extremes.  Tools like Claude code, Cursor and Copilot can take on tasks at a variety of levels depending on how they’re prompted.  You can ask a coding agent to generate a new feature for instance, which might live completely at the logical / syntax level or could end up infringing on architecture if the feature has new architectural considerations or the coding agent introduces a new pattern or dependency.  &lt;/p&gt;
&lt;p&gt;&lt;img title=&#34;features.png&#34; src=&#34;https://cdn.uploads.micro.blog/92198/2025/features.png&#34; alt=&#34;&#34; width=&#34;487&#34; height=&#34;600&#34; border=&#34;0&#34;&gt;&lt;/p&gt;
&lt;h2&gt;Who decides what?&lt;/h2&gt;
&lt;p&gt;As I’m personally moving back into more of a heavy coding role this month, I find this framework of who is making decisions helpful.  &lt;/p&gt;
&lt;p&gt;While building enterprise software at work, I’m ultimately responsible for the quality of all the code I write, so while I find it helpful to move faster by using AI tools to get a rough solution in place, I encode some decisions through the prompts I give and end up reviewing and tweaking everything to make sure what comes out of PRs I open represents my decisions.  I’m also quickly building an intuition for which tasks a coding agent is likely to produce a useful output for that I need to tweak, vs one where I’m unlikely enough to agree with the decisions that its faster to just write it myself&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;On the other hand if I want to experiment with something quick and dirty or prototype a concept, the freedom these tools give to ignore every level below the functional one is wonderful (I just don’t want to maintain such a system).  &lt;/p&gt;
&lt;p&gt;Working with these tools has reminded me once again that reality has a surprising amount of detail.  There is no magic in the world and decisions are always going to have to be made.  If coding tools help us to go faster by focusing more on the decisions that really matter, I’m excited to see what they help us bulid. &lt;/p&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;Ok given the huge ecosystem of choices and configuration in cloud computing its probably more accurate to say that it changes the decisions devs need to make&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;Given the rapid evolution of the tools of course, this is something that needs to be checked over time.  Claude Sonnet can do things reliably that Chat GPT3.5 would consistently fail on, and the agentic system seems to have a good deal of impact on quality as well.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>Retraining our Brains To Review LLM-augmented work</title>
      <link>https://benmccormick.org/2025/07/22/retraining-our-brains-to-review.html</link>
      <pubDate>Tue, 22 Jul 2025 10:05:07 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2025/07/22/retraining-our-brains-to-review.html</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Something I worry about with generative AI in business and commercial use: almost no one fully reads anything in those environments.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Now imagine when even the author hasn&amp;rsquo;t read what was written&amp;hellip; yikes. How does AI writing and reading impact this reality?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&#34;https://hardcoresoftware.learningbyshipping.com/p/234-if-writing-is-thinking&#34;&gt;Steven Sinofski has an interesting post here about “slop” at work&lt;/a&gt;.  I think about this in terms of heuristics.  Our brains are lazy and we all naturally develop “shortcuts” to evaluating a piece of work.  Historically seeing a PRD or tech spec that was fully fleshed out with diagrams and clear explanations of context was a good indication that some serious work and discovery had gone into the document.  A PR full of detailed test cases indicated attention to detail, and that thought had gone into all the possible edge cases.  But with LLMs it is easy to take a few half thought through bullet points and make them look credible, or generate plausible test cases at scale.&lt;/p&gt;
&lt;p&gt;We’re going to need to retrain our brains.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>A Simple Path To Building Trust</title>
      <link>https://benmccormick.org/2024/06/25/a-simple-path.html</link>
      <pubDate>Tue, 25 Jun 2024 14:22:10 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2024/06/25/a-simple-path.html</guid>
      <description>&lt;p&gt;Being trusted is a superpower at work and in life.  When we&amp;rsquo;re trusted things move faster.  Communication is more open, people become more cooperative, and work becomes more enjoyable as relationships can grow deeper.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve found that there&amp;rsquo;s a very simple&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; formula to building people&amp;rsquo;s trust.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s the formula:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Identify a need&lt;/li&gt;
&lt;li&gt;Say you will meet the need. Say when you&amp;rsquo;ll do it by and with what quality.&lt;/li&gt;
&lt;li&gt;Go and do it the way you said you would&lt;/li&gt;
&lt;li&gt;Tell people you did it&lt;/li&gt;
&lt;li&gt;Repeat&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;That&amp;rsquo;s the whole process. Do that enough as an individual and you will develop a reputation for reliability and trust. You&amp;rsquo;ll find that people tell you things and give you more opportunities. If your team does that you&amp;rsquo;ll find that other teams become easier to work with.&lt;/p&gt;
&lt;p&gt;A few notes:&lt;/p&gt;
&lt;h4 id=&#34;misses-count-more-than-makes&#34;&gt;Misses count more than makes&lt;/h4&gt;
&lt;p&gt;Fairly or unfairly, one missed commitment is more memorable than 4 that were completed on time.  If you&amp;rsquo;re operating at a trust deficit it will take time to rebuild trust, but the process is the same.&lt;/p&gt;
&lt;p&gt;When you do miss, always try to miss early and clearly.  Nothing erodes trust like discovering that somebody has been hiding failure.&lt;/p&gt;
&lt;p&gt;Sometimes you&amp;rsquo;ll discover that while you don&amp;rsquo;t have to miss, your commitment no longer makes sense after making it: priorities have changed, new information has emerged, or another opportunity has presented itself.  You can choose to make changes in this situation.  If you communicate the change and your reasoning early to the people you&amp;rsquo;ve committed to&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;, this probably won&amp;rsquo;t be counted as a true miss.  However it probably won&amp;rsquo;t build trust either, and if you&amp;rsquo;re regularly doing this you may create the impression that no plans can be relied upon if you&amp;rsquo;re involved.  The tradeoffs here will vary based on context.&lt;/p&gt;
&lt;h4 id=&#34;people-can-hold-you-to-implicit-expectations&#34;&gt;People can hold you to implicit expectations&lt;/h4&gt;
&lt;p&gt;You can lose trust if you share a secret, even if you never explicitly promised not to tell anybody the secret.  You may lose trust at work if you don&amp;rsquo;t meet some standard of quality that other team members are hitting, even if the expectation wasn&amp;rsquo;t explicitly stated.  This is also why it&amp;rsquo;s useful to say when and at level of quality you&amp;rsquo;re committing to something - if you think you&amp;rsquo;re committing to a rough draft of a tech doc by next week but your manager is expecting a polished doc to be done by Friday, you&amp;rsquo;ll lose trust even if you hit what you think you&amp;rsquo;re committing to.  Since misses count more than make its important to understand and clarify any implicit expectations you might be held to&lt;/p&gt;
&lt;h4 id=&#34;people-trust-kindness&#34;&gt;People trust kindness&lt;/h4&gt;
&lt;p&gt;When you&amp;rsquo;re kind to others they want to trust you and are more likely to overlook or forgive misses.  Jerks fight an uphill battle to earning others&#39; trust.&lt;/p&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;As always, simple does not mean easy.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;For work tasks it may not always be clear who is counting on your commitments: other departments might have been promised this work by somebody else, or be relying on another project that is dependent on your work.  Be careful here.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>Setting Expectations: 4 key areas for performance management</title>
      <link>https://benmccormick.org/2023/02/12/setting-expectations-key.html</link>
      <pubDate>Sun, 12 Feb 2023 17:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2023/02/12/setting-expectations-key.html</guid>
      <description>&lt;p&gt;Performance management processes have been different at every company I’ve worked in, ranging from “basically non-existent” at a 15 person startup to “months of work for managers each review period followed by clear expectations that growth feedback will be given throughout the year” in big tech world.  Some of these differences are good and bad, most are more about the context of the company.  I’ve found that regardless of process there are 4 things that it’s important for a team member to align with their manager on throughout the year.  Hopefully there’s process supporting this, but if not both the team member or the manager can take the initiative to make it happen.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Focus -&lt;/strong&gt; Where should the teammate be putting their energy?  Depending on seniority and the level of change within the organization, this might be something to resync on every 6 months, monthly, weekly or even daily[^1].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Baseline Expectations -&lt;/strong&gt; It’s important to agree not just what you’re trying to do but what results are expected.  This means being clear on what a team member is and isn’t responsible for, what success looks like, and giving feedback when the manager believes things are off track or a miss has occurred.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Opportunities -&lt;/strong&gt; This is about above and beyond.  What things aren’t expected but could be an opportunity for growth (to help the team/business, show that the teammate is ready for a promotion, or ideally both)?  It’s useful to clearly delineate these from expectations, so that you don’t risk a lack of clarity on what is “good enough”, which can cause unnecessary stress/burnout or poor prioritization.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Risks&lt;/strong&gt; - I find that this part is usually left implicit, but its helpful to align up front on what likely areas of failure might be, where the teammate and manager see the most risk of missing expectations (or finding out that the expectations weren’t correct!).  This could be due to ambiguity, a known skill gap from the team member or those they’re collaborating with, a new type of challenge, or business level needs/expectations that aren’t realistic.&lt;/p&gt;
&lt;p&gt;[^1] Long term syncing daily on priorities/focus areas might be micro-managing or a sign that the team member is struggling to manage their own work, but it can be useful in a rapidly changing environment or during onboarding for a time&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>3 Pillars For Effective Work</title>
      <link>https://benmccormick.org/2023/01/13/pillars-for-effective.html</link>
      <pubDate>Fri, 13 Jan 2023 07:33:53 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2023/01/13/pillars-for-effective.html</guid>
      <description>&lt;p&gt;There are 3 primary reasons why one human may be more effective than another in a given work situation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Caring&lt;/strong&gt; - All things being equal, somebody who cares more about a problem / product will generally be more effective&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.  Caring can range from &amp;ldquo;startup founder&amp;rdquo; level obsession to being completely checked out, and effectiveness will vary on that spectrum.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Capacity&lt;/strong&gt; - The amount of time and mental resources a team member can bring to a problem matters and will vary over time.  Illness, stress, a busy personal season or competing work priorities can reduce this temporarily for anyone.  Some people will have longer term lower capacity than others due to factors like life circumstances, health, and outside of work commitments.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Leverage&lt;/strong&gt; - People&amp;rsquo;s skills, experiences, tendencies, relationships and abilities can allow them to be disproportionately effective or ineffective in different situations.  Some of this is situational: &amp;ldquo;he wrote that library and knows all the details&amp;rdquo;, &amp;ldquo;she is an expert on this technology&amp;rdquo;, &amp;ldquo;he has admin privileges on this system&amp;rdquo;, &amp;ldquo;she knows the tech lead on that team&amp;rdquo;. Other factors like communication ability, broad technical experience, or credibility within an org tend to persist across problems.&lt;/p&gt;
&lt;p&gt;When trying to understand why somebody is more or less effective than [their peers | what you expected | your own performance], it is useful to pull out this model&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;.  Trying to help somebody who is capacity constrained level up their skills likely won&amp;rsquo;t move the needle.  On the other hand, if you have team members who have the skills but lack capacity or don&amp;rsquo;t care about their work, there may be an opportunity to help address those underlying challenges and get a better outcome.  Similarly if you&amp;rsquo;re trying to &amp;ldquo;outwork&amp;rdquo; your way to a promotion while you see peers who seem to be doing less than you getting better outcomes, its worth looking into what leverage they might have (skills, access, relationships) that are helping them be more efficient.&lt;/p&gt;
&lt;p&gt;A caveat: be careful not to prejudge caring vs capacity issues in others. It can be difficult to tell whether somebody seems disengaged because they don&amp;rsquo;t care, or because they don&amp;rsquo;t have capacity to care.  Best to work through that with them before solutioning.&lt;/p&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;Caveat &amp;ndash; if the level of care for a sub-section of a product/problem/org is disproportionate to the business value, this can become a negative.  Think of an employee who spends their time improving line-level code quality of a feature that the team intends to deprecate.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;I don&amp;rsquo;t recommend it for hiring however &amp;ndash; trying to judge &amp;ldquo;caring&amp;rdquo; can tend toward unconscious biases, and most long term capacity issues fall under protected categories / more explicit biases.  Better to focus on proven previous effectiveness and testable &amp;ldquo;leverages&amp;rdquo; (tech/people skills / knowledge)&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>2022 Books</title>
      <link>https://benmccormick.org/2023/01/03/books.html</link>
      <pubDate>Tue, 03 Jan 2023 10:47:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2023/01/03/books.html</guid>
      <description>&lt;p&gt;I read 13 &amp;ldquo;work related&amp;rdquo; books in 2022&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;. They&amp;rsquo;re broken up by category below.  I didn&amp;rsquo;t think any of these books were &lt;em&gt;bad&lt;/em&gt;, but the ones I would recommend have a star next to them.&lt;/p&gt;
&lt;h3 id=&#34;decision-making&#34;&gt;Decision Making&lt;/h3&gt;
&lt;p&gt;⭐ &lt;a href=&#34;https://amzn.to/3Ga8UFh&#34;&gt;How To Decide&lt;/a&gt; by Annie Duke - Annie Duke takes her poker background and applies it to making decisions in other contexts &amp;ndash; lots of practical decision making strategies here&lt;/p&gt;
&lt;p&gt;⭐ &lt;a href=&#34;https://amzn.to/3WHknDc&#34;&gt;The Scout Mindset&lt;/a&gt; by Julia Galef — somewhat similar ground to to &amp;ldquo;How You Decide&amp;rdquo;, but more of a focus on viewing the world objectively.  I really enjoyed reading these 2 books together.&lt;/p&gt;
&lt;h3 id=&#34;productivity&#34;&gt;Productivity&lt;/h3&gt;
&lt;p&gt;⭐ &lt;a href=&#34;https://amzn.to/3YXmXXg&#34;&gt;Make Time&lt;/a&gt; by Jake Knapp and John Zeratsky — A nice book full of practical tips for managing your time and reclaiming control from distractions&lt;/p&gt;
&lt;h3 id=&#34;product-process&#34;&gt;Product Process&lt;/h3&gt;
&lt;p&gt;⭐ &lt;a href=&#34;https://amzn.to/3WHwnEX&#34;&gt;The Messy Middle&lt;/a&gt; by Scott Belsky — The best description of what it&amp;rsquo;s like working in a &amp;ldquo;startup land&amp;rdquo; situation (either a real startup or high change/growth in a larger company) that I&amp;rsquo;ve read.  Plenty of good practical wisdom as well&lt;/p&gt;
&lt;p&gt;⭐ &lt;a href=&#34;https://amzn.to/3YXmXXg&#34;&gt;Escaping the Build Trap&lt;/a&gt; By Melissa Perri — This book lays out a great vision for what a healthy product organization looks like.  As a non-product manager, I&amp;rsquo;ve found it mostly helpful for recognizing when things are going wrong and giving feedback.&lt;/p&gt;
&lt;p&gt;⭐ &lt;a href=&#34;https://amzn.to/3WHvQCX&#34;&gt;Kill It With Fire&lt;/a&gt;  by Marianne Bellotti — An engaging review of how to work with legacy systems (the title is ironic) with lots of real world examples and principles that apply even for newer systems.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://amzn.to/3VG3kA7&#34;&gt;The Lean Startup&lt;/a&gt; by Eric Ries — This book is very well regarded and I don&amp;rsquo;t remember disagreeing with anything as I went through it about a year ago, but it left no impression on me.  Possibly I&amp;rsquo;d already absorbed the main ideas through other sources?&lt;/p&gt;
&lt;h3 id=&#34;soft-skills&#34;&gt;Soft Skills&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://amzn.to/3WGLWwm&#34;&gt;The Speed of Trust&lt;/a&gt; by Stephen M.R. Covey — A look at how to build trust in business and why its important&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://amzn.to/3Q8O0ec&#34;&gt;Rituals For Virtual Meetings&lt;/a&gt; by Kursat Ozenc and Glenn Fajardo — This was more of a workbook, with a ton of examples of possible &amp;ldquo;rituals&amp;rdquo; that you could implement during remote meetings.  I in theory like this idea, in practice most of these felt too hokey for me to try &amp;ndash; but if you&amp;rsquo;re willing to go full &amp;ldquo;icebreaker game&amp;rdquo; for your team meetings, this has good ideas.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://amzn.to/3Ihw0MK&#34;&gt;The Culture Map&lt;/a&gt; by Erin Meyer — Another book that I read a year ago that I don&amp;rsquo;t feel I&amp;rsquo;ve retained very well — but the big idea was that business communication and practice varies wildly across cultures and its important to understand the background of the people you work with.&lt;/p&gt;
&lt;h3 id=&#34;career&#34;&gt;Career&lt;/h3&gt;
&lt;p&gt;⭐ &lt;a href=&#34;https://amzn.to/3WxFec9&#34;&gt;The Staff Engineer&amp;rsquo;s Path&lt;/a&gt; by Tanya Reilly —  My most recently completed book, this was a great exploration of the &amp;ldquo;advanced IC&amp;rdquo; career path.  I&amp;rsquo;ll have a longer review coming later, but this was my favorite work related book of the year.&lt;/p&gt;
&lt;h3 id=&#34;miscellaneous&#34;&gt;Miscellaneous&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://amzn.to/3GdVJDr&#34;&gt;Product Led Growth&lt;/a&gt; by Wes Bush — This was pretty specific to a work project, but a decent review of the business requirements for moving to a product led growth model rather than sales driven.  Useful for folks who are bootstrapping a new SaaS business or trying to move to PLG.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://amzn.to/3WTWyYy&#34;&gt;Building For Everyone&lt;/a&gt; by Annie Jean-Baptiste — This is a high level overview of accessibility and inclusive design practices by a design leader at Google.  I wanted to like this more than I did &amp;ndash; a lot of the content here is about changing large organizations to institute more inclusive design practices, I had been hoping for more &amp;ldquo;local&amp;rdquo; things that I could learn to get better here.&lt;/p&gt;
&lt;h2 id=&#34;going-forward&#34;&gt;Going Forward&lt;/h2&gt;
&lt;p&gt;One of my 2023 goals is to spend more time with fewer books, including taking deeper notes on some books that I&amp;rsquo;ve read in the past which had interesting ideas that I don&amp;rsquo;t feel I&amp;rsquo;ve retained well.  In particular I want to revisit Scout Mindset and Escaping The Build Trap from this year and am already writing up notes for Staff Engineer&amp;rsquo;s path.&lt;/p&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;You can see non-work related books on &lt;a href=&#34;https://bbn.benmccormick.org/2023/01/02/books-read-in.html&#34;&gt;my &amp;ldquo;non-tech&amp;rdquo; blog&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>7 Months of Lifting At Home</title>
      <link>https://benmccormick.org/2022/12/28/months-of-lifting-at-home.html</link>
      <pubDate>Wed, 28 Dec 2022 15:38:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2022/12/28/months-of-lifting-at-home.html</guid>
      <description>&lt;p&gt;I picked up a new hobby this year &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;!  For years I viewed weightlifting as a form of benefial drudgery that I occasionally tolerated but one I have mostly avoided post-college.  Then last November I joined a cross-fit style gym and was introduced to Olympic/Powerlifting style barbell lifting.  The gym didn&amp;rsquo;t stick for reasons that had more to do with schedule than anything else, but I pulled my favorite part of it out and have been consistently doing barbell lifting at home since May.&lt;/p&gt;
&lt;img style=&#34;display:block; margin-left:auto; margin-right:auto;&#34; src=&#34;https://cdn.uploads.micro.blog/92198/2026/0644ce27c0.jpg&#34; alt=&#34;My home gym setup&#34; title=&#34;68073380266__B9AAB6FA-B471-4E46-BF16-053F76C21B14.jpeg&#34; border=&#34;0&#34; width=&#34;450&#34; height=&#34;600&#34; /&gt;
&lt;p&gt;This has been an unexpectedly rewarding experience for me.  It&amp;rsquo;s allowed me to develop a consistent exercise routine with 2 kids in the house (something thats eluded me since Elena was born 4 years ago), reminded me that I can still learn new things at 35, and helped me feel physically the best I&amp;rsquo;ve felt in a decade.  My original goal was to help myself have energy for my kids, and I definitely think I&amp;rsquo;ve achieved that.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve been running through the &lt;a href=&#34;https://amzn.to/3jC6ibu&#34;&gt;Starting Strength&lt;/a&gt; program, unmodified for 3 months and then shifting to a 4 day schedule for the last 4 months.  In practice this meant primarily focusing on 5 exercises: the Squat, Bench Press, Overhead Press, Deadlift and Power Clean &lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;.  Initially the schedule looked like this, alternating between A &amp;amp; B 3 days a week&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Workout A&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Workout B&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Squat&lt;/td&gt;
&lt;td&gt;3x5&lt;/td&gt;
&lt;td&gt;Squat&lt;/td&gt;
&lt;td&gt;3x5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bench Press&lt;/td&gt;
&lt;td&gt;3x5&lt;/td&gt;
&lt;td&gt;Press&lt;/td&gt;
&lt;td&gt;3x5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Power Clean&lt;/td&gt;
&lt;td&gt;3x5&lt;/td&gt;
&lt;td&gt;Deadlift&lt;/td&gt;
&lt;td&gt;3x5&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Doing that much squatting became exhausting around the summer, the workouts became long as I needed longer breaks between sets and I decided I wanted a bit more upper body focus (and better legs for when I was playing basketball and going for walks).  So I switched to a 4x a week schedule:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tuesday&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Wednesday&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Saturday&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Sunday&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Squat&lt;/td&gt;
&lt;td&gt;3x5&lt;/td&gt;
&lt;td&gt;Bench Press&lt;/td&gt;
&lt;td&gt;3x5&lt;/td&gt;
&lt;td&gt;Deadlift&lt;/td&gt;
&lt;td&gt;3x5&lt;/td&gt;
&lt;td&gt;Bench Press&lt;/td&gt;
&lt;td&gt;3x5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Power Clean&lt;/td&gt;
&lt;td&gt;3x5&lt;/td&gt;
&lt;td&gt;Press&lt;/td&gt;
&lt;td&gt;3x5&lt;/td&gt;
&lt;td&gt;Light Squat&lt;/td&gt;
&lt;td&gt;3x5&lt;/td&gt;
&lt;td&gt;Press&lt;/td&gt;
&lt;td&gt;3x5&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Those are the core lifts &amp;ndash; this doesn&amp;rsquo;t include warmups (I usually did a Peloton strectch workout and worked my way up to heavy weights) or accessory exercises (I tried to do rows / ab workouts / pushups on days I was feeling good and having time in the 4xweek schedule)&lt;/p&gt;
&lt;p&gt;Because I had effectively never trained for any of these lifts in a serious way before, I got to see a lot of relatively easy progress just from staying consistent in lifting.  The chart below shows the change in my 5 rep max #s throughout the year (these are training numbers &amp;ndash; I haven&amp;rsquo;t been trying to set up for specific max attempts).&lt;/p&gt;
&lt;img style=&#34;display:block; margin-left:auto; margin-right:auto;&#34; src=&#34;https://cdn.uploads.micro.blog/92198/2026/a1a6055ae9.png&#34; alt=&#34;Screenshot on 2022 12 28 at 13 25 00&#34; title=&#34;Screenshot on 2022-12-28 at 13-25-00.png&#34; border=&#34;0&#34; width=&#34;599&#34; height=&#34;375&#34; /&gt;
&lt;p&gt;Other than a lag in August / September when I traveled and then got sick, I&amp;rsquo;ve been able to make fairly consistent progress on all of the lifts throughout the year, with some exceptions where I was reworking my form/technique (for DL in June and Squat/Powerclean recently).  Overall I&amp;rsquo;m really pleased with my progress.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Exercise&lt;/th&gt;
&lt;th&gt;Initial 5RM&lt;/th&gt;
&lt;th&gt;Best 5RM&lt;/th&gt;
&lt;th&gt;% increase&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Squat&lt;/td&gt;
&lt;td&gt;175&lt;/td&gt;
&lt;td&gt;320&lt;/td&gt;
&lt;td&gt;82%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bench Press&lt;/td&gt;
&lt;td&gt;135&lt;/td&gt;
&lt;td&gt;240&lt;/td&gt;
&lt;td&gt;77%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Press&lt;/td&gt;
&lt;td&gt;95&lt;/td&gt;
&lt;td&gt;145&lt;/td&gt;
&lt;td&gt;52%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deadlift&lt;/td&gt;
&lt;td&gt;205&lt;/td&gt;
&lt;td&gt;385&lt;/td&gt;
&lt;td&gt;87%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Power Clean (3RM)&lt;/td&gt;
&lt;td&gt;65&lt;/td&gt;
&lt;td&gt;170&lt;/td&gt;
&lt;td&gt;161%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pendlay Row&lt;/td&gt;
&lt;td&gt;130&lt;/td&gt;
&lt;td&gt;190&lt;/td&gt;
&lt;td&gt;46%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;I do think I&amp;rsquo;m reaching the end of my &amp;ldquo;linear progression&amp;rdquo;, and going heavy on legs also wears me out for basketball, which is still my favorite form of exercise.  So going into the new year I&amp;rsquo;m going to be switching to &lt;a href=&#34;https://www.t-nation.com/workouts/5-3-1-how-to-build-pure-strength/&#34;&gt;5/3/1&lt;/a&gt; with a goal of slower but steady progress while also keeping my legs a bit more intact for basketball and exploring other goals rather than just moving numbers for the core lifts.&lt;/p&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;Technically 2, I also started smoking meats &amp;ndash; a nice complementary habit to lifting :)&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;The original program also includes back extensions and chinups &amp;ndash; I&amp;rsquo;ve been swapping in rows instead, but I want to get to chinups in the new year&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>Mental Models For Managing Change</title>
      <link>https://benmccormick.org/2022/01/24/190000.html</link>
      <pubDate>Mon, 24 Jan 2022 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2022/01/25/190000.html</guid>
      <description>&lt;p&gt;&lt;em&gt;This article was first published in my newsletter, &lt;a href=&#34;https://herdinglions.benmccormick.org/&#34;&gt;Herding Lions&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;At this point I’ve spent the large majority of my career working in startups at different stages. While life can look very different in a 15 person early stage startup and a 300 employee growth stage startup, one thing that is constant across every startup I’ve encountered is a rapid pace of change and a relatively short time horizon for planning. Plans aren’t made for too long in advance, and yet often still manage to change significantly before reaching the original goal. Even in more stable environments, the reality is every software project is a unique undertaking to bring something new into the world. That brings an unavoidable level of unpredictability, meaning that everyone working in software must accept dealing with changing plans and priorities.&lt;/p&gt;
&lt;p&gt;Some common questions predictably come with this state of affairs. How much change is too much? For a specific change, why are we doing this instead of sticking to our original plan? As engineering leaders we need to be able to both make choices about what changes to advocate for and push back on, and also learn how to explain those choices to our teams and other folks we work with.&lt;/p&gt;
&lt;p&gt;I’ve found 2 different models helpful for thinking about changes in plans.&lt;/p&gt;
&lt;h3 id=&#34;understandingthelevelofthechange&#34;&gt;Understanding the level of the change&lt;/h3&gt;
&lt;p&gt;Changes in roadmap can come in at a few different levels. Understanding the level can help you understand how to think about it, and how to talk to your team about it.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;A consequence of existing ambiguity&lt;/strong&gt; This occurs when a team didn’t have clear committed plans previously or didn’t communicate them clearly elsewhere. This is less of a change and more a symptom of ongoing chaos. If a situation like this persists, it is the Engineering Manager’s problem to fix.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;A higher level need&lt;/strong&gt; A team is sometimes asked to do something that doesn’t directly tie into its mission, but is important for the broader company. Examples include helping another team with their project, or working on a revenue driving sales ask that wasn’t part of the original product roadmap.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Higher level requests are important to take seriously and often are the right thing to do. But if they become a regular pattern it can be a sign that your team doesn’t have the right mission, or you’re getting sucked into thinking too short term.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;A tactical change&lt;/strong&gt; When working on a project a team often learns about new and better ways to achieve their goals. A different approach to code, a new feature that moves the same goal, or putting different people with a new perspective on a problem are all new pieces of.information that serve as opportunities to make a better plan.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Tactical changes are normal and a sign that you’re paying attention to what you learn as you go. However, If you’re making these type of changes repeatedly, they’re not tied to a clear lesson from the work you’re doing, or you’re making similar tweaks on every project (looks like we need to add unexpected time for more testing again) it might be a sign that you didn’t properly plan or the team isn’t aligned on a goal.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;A strategic change&lt;/strong&gt; Sometimes teams change plans because their overall approach to achieving their goals has changed. Maybe they’ve decided to focus on a specific segment of their customer base or realized they need to focus on building up our quality before releasing new features.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The most important thing with strategic changes is clear communication – do your team and the stakeholders around your team understand not just what new work you’re doing, but also the strategic change behind it? If not, that misalignment can quickly move a project into muddy waters.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;A change in mission&lt;/strong&gt; Sometimes a team’s whole purpose can change. This often corresponds with a reorg or a higher level strategic change in the company. These changes should be rare, but are a good opportunity for a team to increase its impact.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;After a change in mission expect to spend a lot of time learning, helping teammates work through the change, and handling a period of other change requests – because by default you’ve found your way back to ambiguity and it is your job to work your way out of that.&lt;/p&gt;
&lt;h3 id=&#34;trackyourstabilityovertime&#34;&gt;Track Your Stability Over Time&lt;/h3&gt;
&lt;p&gt;Beyond examining individual changes it can be helpful to keep track of how often you’re changing your plans over time. Some teams are naturally more stable, while others change plans more often. These aren’t necessarily descriptions of virtue – a team that never changes its plan can end up being slow to respond to environment changes and continue for months on low impact work, but a team that is constantly changing plans may never hold a direction long enough to make a dent in any problem. It’s best to consider this along 2 axes, level of change and level of impact.&lt;/p&gt;
&lt;figure&gt;&lt;img title=&#34;changechart.png&#34; src=&#34;https://benmccormick.micro.blog/uploads/2022/7da64f9a2b.png&#34; alt=&#34;Chart showing the change model&#34; width=&#34;600&#34; height=&#34;326&#34; border=&#34;0&#34; /&gt;&lt;/figure&gt;
&lt;p&gt;Teams that are stagnant may need to consider more aggressively seeking feedback on their approach from users and consider making changes, or finding a higher value mission that is unlocking more impact over time.&lt;/p&gt;
&lt;p&gt;Teams that are churning on the other hand might need to commit to finishing more, even if that means being a bit less responsive to new requests or opportunities. A discipline of making and then completing small time bound goals can be helpful here.&lt;/p&gt;
&lt;p&gt;Of course there’s a fine line between stagnant and steady, churning and adaptive. An approach that was working before might go stale, and a team that appears stagnant may be in the early stages of unlocking a big iterative return. So this model should be used carefully, but it is helpful to have an opinion on where your team stands today as you consider new requests to change your plans.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>More Thoughts On Time</title>
      <link>https://benmccormick.org/2022/01/10/more-thoughts-on-time.html</link>
      <pubDate>Mon, 10 Jan 2022 21:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2022/01/10/more-thoughts-on-time.html</guid>
      <description>&lt;p&gt;&lt;em&gt;This article was first published in my newsletter, &lt;a href=&#34;https://herdinglions.benmccormick.org/&#34;&gt;Herding Lions&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;In my &lt;a href=&#34;https://benmccormick.org/2021/12/14/think-about-time&#34;&gt;last post&lt;/a&gt; I listed some process tips for how to manage your time as an engineering leader. Continuing that thought, in the spirit of new habits in the new year this week will explore the question of how to choose what to focus on with the time that you do have. After all, efficiency is only valuable if it is pointed in a worthwhile direction.&lt;/p&gt;
&lt;p&gt;Generally the time on my schedule can be divided into 3 categories - ongoing rhythms, one off must-dos, and opportunities. Each of these requires a different strategy.&lt;/p&gt;
&lt;h3 id=&#34;rhythms&#34;&gt;Rhythms&lt;/h3&gt;
&lt;p&gt;Rhythms are my word for any activity or task that takes place on a regular cadence (daily / weekly / monthly / quarterly). As EMs we’re likely to have rhythm meetings focused around our teams (standups, 1-1s, quarterly planning, performance reviews), as well as upward and outward rhythms (staff meetings or regular cross-departmental syncs), and personal rhythms (clearing time each week to write a status report, or do code reviews or review the backlog).&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If you get one percent better each day for one year, you’ll end up thirty-seven times better by the time you’re done. - &lt;a href=&#34;https://jamesclear.com/continuous-improvement?utm_campaign=Herding%20Lions&amp;amp;utm_medium=email&amp;amp;utm_source=Revue%20newsletter&#34;&gt;James Clear&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Healthy rhythms are extremely valuable. When you thoughtfully invest in relationships or valuable work on a regular basis, that investment can compound and redefine the type of impact you and your team can achieve. And regular maintenance of important relationships or projects can also help you stay informed and aware when things are off. When I plan out my quarters and years, I spend much more time on figuring out what rhythms and habits I want to maintain or develop than setting goals, because it’s the regular investment of time that ultimately leads us wherever we end up.&lt;/p&gt;
&lt;p&gt;However, not all rhythms are healthy and inefficient rhythms that are not thoughtfully moving you toward some broader goal can be a painful tax on your productivity and your sense of well-being. Almost everyone who has done time in the corporate world has had the experience at some point of regularly attending a meeting that seemed to provide little value to many or all of the participants, where engagement was low and morale was lower. This type of “rhythm” can easily have negative externalities where it wastes not just the hour in the meeting but time before where you’re dreading it and time after when you’re recovering as well.
Better time management with regard to rhythms means designing your rhythms. That means understanding the &lt;strong&gt;why&lt;/strong&gt; behind each recurring calendar event and taking steps to remove or redeem the low and negative value ones. &lt;a href=&#34;https://benmccormick.org/2021/11/03/good-meetings-are-designed&#34;&gt;I covered this for meetings a few weeks ago&lt;/a&gt;, but the principles apply to any regular use of time. It also means taking the time to evaluate your goals and focus areas and consider whether there are any rhythms you &lt;strong&gt;should&lt;/strong&gt; be investing in that might allow you to unlock the type of compound gains that require regular time. This could be clearing time for networking, building a new skill, 1-1s with key peers, or just dedicated “focus time” that you block and protect for deep work.&lt;/p&gt;
&lt;h3 id=&#34;must-dos&#34;&gt;Must-Dos&lt;/h3&gt;
&lt;p&gt;Ok so this is the tricky one — what if you’re drowning in “must do” work? There may be seasons where you really are filling your calendar with mostly one-off non-recurring work. If this is a short term season with a clear ending (a big project push, a switch to a new team or company) that may be fine, but this is an area to tread carefully. When we perceive a large chunk of work as things we &lt;strong&gt;must&lt;/strong&gt; do, it becomes much harder to be thoughtful about balancing our priorities.&lt;/p&gt;
&lt;p&gt;It’s a cliché, but the key for this type of work is developing a healthy ability to say no, as well as good rhythms of prioritizing and evaluating your time. EMs who say yes to everything will quickly overwhelm themselves, and even worse will overwhelm and burn out their teams; so the ability to say &lt;strong&gt;no&lt;/strong&gt; in a way that is effective and doesn’t burn bridges within your organization is a key skill. But often time work that we’re pushed to do &lt;strong&gt;is&lt;/strong&gt; valuable. So the key is to make sure you’re prioritizing thoughtfully, and that takes time. I have a few questions that I commonly ask when considering external requests (or marching orders passed from above)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Is this a high leverage activity?&lt;/strong&gt; I love Andy Grove’s model of manager time being valued in terms of leverage, or how much impact an action has relative to time/effort commitment. For asks of both me personally and my team, it’s helpful to see whether this is an incremental win or something that will enable more value over time. You can also think about this in terms of return on investment.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Can somebody else do this?&lt;/strong&gt; For EMs, almost any work that can be done by somebody else on their team should be done by somebody else. Especially if you feel like you’re spending a high amount of time on urgent “must do” work. Give away your Legos, develop your time and clear your time to work on higher level work.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Can I do less here?&lt;/strong&gt; When people are making external requests of you, most of the time they’ll ask for everything they think they might want up front, and are not thinking about your schedule. If the work isn’t core to your responsibilities, it’s always worth asking if there is a scrappier solution that will still make people happy. There’s a fine line to walk here — you don’t want to become known for skimpy/sloppy work, but it’s important to develop a habit of understanding what level of quality is needed for a task. People are used to making cost vs speed vs quality choices, and can usually help you understand their priorities if you frame things in that light (I can do it like this now, or do the full thing next month. If you need the full thing now it will mean stopping all work on some other thing they care about)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;opportunities&#34;&gt;Opportunities&lt;/h3&gt;
&lt;p&gt;The final category of work is the most likely to get pushed off your category. This is work that won’t blow up if its neglected, might not ever be asked about, and in many cases isn’t visible to the rest of your org at first. This is taking the time to do a deep dive on understanding the quality issues on your “problem feature”, writing a reusable onboarding plan for your team to make it easier to add new teammates or clearing time to organize a brainstorming session on future roadmap activities. If you don’t already have ideas of what this might be for you, you could always start with clearing time to think about what areas your team could most improve in and your top ideas for addressing those problems.&lt;/p&gt;
&lt;p&gt;This type of strategic deep work is an important part of having a team that is continuously improving. Without time to identify and understand problems, and time to address those issues, most teams will stagnate. And while that leadership can come from anywhere, on many issues it is often most impactful and most practical for it to start with an EM. The key skill for opportunities is to keep an identified list of your top strategic opportunities and priorities so that as time does become available to work on them, you’re ready to take advantage and don’t automatically fill that time with lower priority work.&lt;/p&gt;
&lt;p&gt;Every EMs calendar is going to shift over time, with some months bringing more opportunities and others resembling more of a fire fighting session. But consistent habits of designing your rhythms, carefully evaluating the asks that come in to you and your team, and identifying and prioritizing key opportunities can go a long way. An Engineering Manager’s calendar abhors a vacuum and time will fill up. Invest in making sure that it goes to the right things.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>How I Think About Time</title>
      <link>https://benmccormick.org/2021/12/13/190000.html</link>
      <pubDate>Mon, 13 Dec 2021 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2021/12/14/190000.html</guid>
      <description>&lt;p&gt;&lt;em&gt;This article was first published in my newsletter, &lt;a href=&#34;https://herdinglions.benmccormick.org/&#34;&gt;Herding Lions&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;One of the biggest challenges every engineering leader faces is making decisions on how best to use their time. Every engineering team I’ve ever seen has more opportunities than capacity, and leaders can always do more.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;My day always ends when I’m tired and ready to go home, not when I’m done. &lt;strong&gt;I am never done&lt;/strong&gt;. - Andy Grove&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Below are 4 lessons I’ve learned about using time well during my time as a manager.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Time is your primary resource as a manager, and it is finite&lt;/strong&gt;. The Andy Grove quote above is challenging. When we can always do more, there aren’t natural boundaries that tell us when to stop. For individual contributors this can get managed without much intention through the rhythms of sprints / projects / the rate that product managers can assign work. EMs tend to be expected to generate their own work and there are fewer natural cues to tell you that you’ve done “enough”. As a result, management tends to be next level time management, and that means you need to start by defining some boundaries (when will you choose to go home and sign off?) and learning to be intentional with your time. A lack of boundaries, or setting your boundaries based on demand in an unbounded way is a sure path to burnout. This is a lesson I’ve had to learn several times personally, as demands on my time have scaled up.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Be careful with the Maker’s Schedule, Manager’s Schedule mindset.&lt;/strong&gt; One of the most famous articles on schedule management in tech is &lt;a href=&#34;http://www.paulgraham.com/makersschedule.html?utm_campaign=Herding%20Lions&amp;amp;utm_medium=email&amp;amp;utm_source=Revue%20newsletter&#34;&gt;Maker’s Schedule, Manager’s Schedule&lt;/a&gt;. In it, Paul Graham breaks down 2 ways of managing your time: manager schedules, where days are neatly divided into hourly blocks, and maker schedules where time is ideally at least in half day uninterrupted blocks (due to the need to do Deep Work / avoid context switching). I think most engineers take the right lesson from this article when they read this and work to protect blocks of time on their calendar better. And many managers empathetically learn from it that they should be considerate of their reports calendars and be careful how they schedule meetings. But there’s a dangerous assumption that people can take from the labels: that once they become a manager, they must be on the manager schedule. Now, plenty of manager’s are on a pure manager’s schedule (I’ve been there). But if you can, working at least partially on a maker’s schedule can unlock a lot more opportunity for creative and strategic work that is difficult to fit into 30 minute blocks scattered throughout your week. The article itself is essentially Graham explaining why he as an “important business person” chooses to operate on a maker schedule against social expectations. So read the article, learn from it, but don’t typecast yourself. Structure your time in the way that lets you have the most impact.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Run your calendar, don’t let your calendar run you.&lt;/strong&gt; On the subject of manager schedules, becoming a manager was the first time in my life I really ran my schedule based off an external calendar, as opposed to primarily relying on my memory for what I needed to do on a day and using calendars and todo lists as a poorly utilized backup plans. Even if you have fewer direct reports and more strategic or technical duties, it’s hart to avoid becoming calendar driven as you move into leadership roles. That said, it’s important to take charge of your calendar, and not let other people structure it for you. That means being judicious about what meetings you accept, and regularly reviewing your recurring meetings for opportunities to prune them, blocking time for strategic and creative work in lengths that allow for deep work and is appropriate to your obligations, and &lt;a href=&#34;https://larahogan.me/blog/manager-energy-drain/?utm_campaign=Herding%20Lions&amp;amp;utm_medium=email&amp;amp;utm_source=Revue%20newsletter#calendar-color-coding-and-defragging&#34;&gt;defragging your calendar&lt;/a&gt; to be as efficient as possible. When I’m running on the busier side I’ve also found it helpful to fully block my day the night before the day starts (if it isn’t already) to prevent last second invitations from sapping up prep or break time in my schedule. Your mileage may vary on that depending on how much you culturally feel you need to be available for last second invites. If you do this I recommend explaining it to your direct reports and give them a path to escalate urgent things to you in order to not appear unavailable or “too busy”.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Clear time to review and improve how you use your time.&lt;/strong&gt; The retro is my favorite “agile ritual”, and I think its difficult to overuse for both teams and individuals. One great use for personal retros is a regular review of where your time is going. Most people seem to have a bad intuitive understanding of this, its helpful to do a short term tracking exercise or reconstruct at the end of a week based on your calendar. This is a good time to prune meetings as mentioned above, identify “important but not urgent” work that is falling through the cracks, and also do a &lt;a href=&#34;https://benmccormick.org/2020/08/31/simple-burnout-triage&#34;&gt;quick burnout triage&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;when-everything-falls-apart&#34;&gt;When Everything Falls Apart&lt;/h3&gt;
&lt;p&gt;All of the above lessons have been very helpful to me, but I’ve struggled to follow some of them at specific points where I feel completely overwhelmed. So my 4 additional lessons here are patterns that I fallback to when I need to dig my way out of insanity.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Do 3 things a day.&lt;/strong&gt; I’ve never been great with task management / productivity systems. I’ve wandered through a bunch of tools and patterns without really developing consistent habits. So I may be a poor person to give advice on this topic. However the most effective habit I’ve had, which I’ve picked up multiple times when things have gotten overwhelming is very simple – pick 3 things to do each day, write them down and then try to do them. Limiting myself to 3, not keeping a backlog and writing the 3 things somewhere I can visually see it has helped me focus and make choices when life felt overwhelming. Long term I’m not sure this is an optimal system – the lack of backlog and long term planning can leave blind spots. But it’s simple, productive, and easy to implement, and a great way to build momentum and prioritize when you’re underwater.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Distinguish between core work and non-core work&lt;/strong&gt; - When things are going well and can feel easy to follow Grove’s advice at the top. I do stuff and then go home. However when you’re juggling 3 plates that are each stacked too high, it can be really hard to know how to stop. At this time it’s very important to draw lines between the essential and nice to have. One dimension I think about with this is core work vs non-core work. There are things I do at work to grow my career, to help others, or just because I’m interested in them. That’s healthy and should be part of my normal rhythms. But in crisis mode it’s important to identify these as things that can be cut down on or dropped. And then actually doing it, even if it’s painful.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Distinguish between glass and rubber balls.&lt;/strong&gt; Similarly, it’s useful to distinguish between glass balls – responsibilities at home or work that won’t come back if you drop them, like being there for a child’s graduation or executing on a career altering project, vs those that we will be able to recover from more easily because there will be more opportunities to make up for it. The distinction between glass and rubber balls will be different for everybody, but Scott Eblin &lt;a href=&#34;https://eblingroup.com/blog/juggling-rubber-or-glass/?utm_campaign=Herding%20Lions&amp;amp;utm_medium=email&amp;amp;utm_source=Revue%20newsletter&#34;&gt;has some good advice here for distinguishing the two&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Choose between doing more things acceptably or a few things well.&lt;/strong&gt; One of my biggest recent challenges as a manager was learning when my own standards for what “doing my job” were making me less impactful. At a time when I had more on my plate than I could reasonably do well, I made a choice to drop responsibilities where I had a real chance to provide value, because I didn’t think I could perform them to my own standards. That’s a defensible choice, but I didn’t really make it intentionally – instead I freaked out and protected myself. An alternative that I didn’t really consider until I’d gotten to a calmer place was accepting a lower standard of performance (and communicating that expectation to others) in return for being able to keep some projects going without having to disrupt others. Neither of these things are globally the right strategy, it will depend on circumstances and what responsibilities you’re balancing. But making the choice to not just commit to something, but to commit to a maintainable level of quality is an important skill and can help you scale yourself as a manager when under high demand.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
</description>
    </item>
    
    <item>
      <title>Values Are How You Scale Culture</title>
      <link>https://benmccormick.org/2021/11/29/190000.html</link>
      <pubDate>Mon, 29 Nov 2021 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2021/11/30/190000.html</guid>
      <description>&lt;p&gt;&lt;em&gt;This article was first published in my newsletter, &lt;a href=&#34;https://herdinglions.benmccormick.org/&#34;&gt;Herding Lions&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I recently had the pleasure of working with a team to help define &lt;a href=&#34;https://medium.com/kustomerengineering/kustomers-engineering-values-80d06dae4306?utm_campaign=Herding%20Lions&amp;amp;utm_medium=email&amp;amp;utm_source=Revue%20newsletter&#34;&gt;Kustomer’s engineering values&lt;/a&gt;. We went through a brainstorming process, got feedback from the team and ended up with a set of values that we believe reflect the best of our culture and how we work. These days this is the type of work that often feels most impactful to me; we’re investing in culture. But earlier in my career I probably would have been deeply suspicious of it. Aren’t values just babble-speak that managers use to justify their existence? Have I become what I once hated?&lt;/p&gt;
&lt;p&gt;&lt;img style=&#34;display: block; margin-left: auto; margin-right: auto;&#34; title=&#34;d1.jpg&#34; src=&#34;https://benmccormick.micro.blog/uploads/2022/e5e141a50d.jpg&#34; alt=&#34;Dilbert Comic&#34; width=&#34;600&#34; height=&#34;187&#34; border=&#34;0&#34; /&gt;&lt;/p&gt;
&lt;p&gt;What I’ve learned through seeing this modeled in healthy organizations (both before and after shifting to management) is that values are how you scale culture as a company grows and evolves. Good values help employees make hard choices, help new employees know how to be productive in an organization, and allow hiring for culture fit in a way that doesn’t just translate to “this person looks like me”.&lt;/p&gt;
&lt;p&gt;This of course doesn’t happen in every (most?) organizations that define a set of values. For values to be useful you need meaningful values that are regularly used well. Otherwise they’re just an easy to make fun of list of words.&lt;/p&gt;
&lt;figure&gt;&lt;img style=&#34;display: block; margin-left: auto; margin-right: auto;&#34; title=&#34;d2.gif&#34; src=&#34;https://benmccormick.micro.blog/uploads/2022/1dbc39f6b4.gif&#34; alt=&#34;Dilbert 2&#34; width=&#34;598&#34; height=&#34;186&#34; border=&#34;0&#34; /&gt;&lt;/figure&gt;
&lt;p&gt;Meaningful values are opinionated tradeoffs and applicable to day to day decisions. Opinionated means that you’re making a choice – values are a decision to prioritize one good over another good, not just to reject something obviously bad. The &lt;a href=&#34;https://agilemanifesto.org/?utm_campaign=Herding%20Lions&amp;amp;utm_medium=email&amp;amp;utm_source=Revue%20newsletter&#34;&gt;agile manifesto&lt;/a&gt; is a good example of this: instead of saying “Quality is good” (duh!) they say prefer working software over comprehensive documentation – a guiding preference that some devs may not embrace and can practically be used to guide decisions. From Kustomer’s values, we choose to “Optimize For Impact”, which means we may move off of something before getting to perfect, and may explicitly ignore some issues if they won’t move the needle. We value “Do What You Say” because we’re targeting a culture of accountability and trust over one that is simply “nice”. These values directly guide how I as a manager might choose to give feedback in a situation, and how an engineer thinks about calculating scope and an estimated due date for a project. Meaningful values are also specific to their context. Instead of writing our own values, Kustomer could have just taken &lt;a href=&#34;https://about.google/philosophy/?utm_campaign=Herding%20Lions&amp;amp;utm_medium=email&amp;amp;utm_source=Revue%20newsletter&#34;&gt;Google’s values&lt;/a&gt;. And we certainly did look at other companies for inspiration. But ultimately values are useful for defining the culture of a company and the behaviors that are successful there, and that will not be the same between 2 companies. If you ask your employees to start behaving like Google employees that will likely lead to some interesting results, but your context isn’t Google’s and ultimately you’ll likely find that what works for a huge multi-national tech giant may not make sense for you. And realistically the values and behaviors that benefited Google as they were a small growing startup may not be the right ones for them today – &lt;a href=&#34;https://gizmodo.com/google-removes-nearly-all-mentions-of-dont-be-evil-from-1826153393?utm_campaign=Herding%20Lions&amp;amp;utm_medium=email&amp;amp;utm_source=Revue%20newsletter&#34;&gt;they’ve even famously shaded away from “Don’t be evil”&lt;/a&gt;. Instead, understand what behaviors and priorities are useful and valued in your current context (some level of aspirational values are appropriate but mostly this should be descriptive of what is effective in your context today), and find ways to communicate those clearly and crisply, preferably using language that you already hear in your company today. It doesn’t mean that you can’t share values with another place or even use a term that is somewhat generic – it just has to have a clear meaning in your culture. Kustomer’s value of “Trust” is somewhat generic as a buzzword, but in practice its a term that has been important throughout our history and internally provides a clear set of priorities – work that threatens our customers’ trust always comes first, and we should always be proactive rather than reactive about quality issues. We also value going fast, but quality comes ahead of velocity. Every new engineer goes through a training where we unpack these concepts, so the value was simply naming something that already existed for us.&lt;/p&gt;
&lt;p&gt;Once you’ve established a set of meaningful values, you still need to regularly put them to use in order to see value. That means referencing them when you make decisions (“We shouldn’t work on this because we need to &lt;strong&gt;optimize for impact&lt;/strong&gt;” or “We can’t ship this without a monitoring strategy – we need to keep our customer’s &lt;strong&gt;trust&lt;/strong&gt;, and we can’t do that if we don’t know when things break”). It also means rewarding behaviors that align with our values. At the company level, Kustomer monthly recognizes an employee who embodies our “Don’t just talk about it, be about it” value with a DJTAIBAI award. I’ve seen other companies experiment with “micro-awards” where employees have a budget for sending other employees rewards that get tied to their values. This also can work into your normal processes of evaluation and recognition by emphasizing behavior that aligns or deviates from values in performance reviews and 1–1 coaching. The more the values get talked about and rewarded as expected behavior, the more they have the power to scale culture.&lt;/p&gt;
&lt;p&gt;Values are a tool for naming the culture you want to have and starting to iterate to it. They don’t guarantee that you’ll get there, and if the values you list aren’t already a meaningful reality for at least part of your company, they’re probably not going to transform your team. But they can help you scale what you have as you grow, and they can help set a bar that will open the path to the difficult conversations needed when things need to change.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Strategies For Building Team Resilience</title>
      <link>https://benmccormick.org/2021/11/14/190000.html</link>
      <pubDate>Sun, 14 Nov 2021 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2021/11/15/190000.html</guid>
      <description>&lt;p&gt;&lt;em&gt;This article was first published in my newsletter, &lt;a href=&#34;https://herdinglions.benmccormick.org/&#34;&gt;Herding Lions&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;In &lt;a href=&#34;https://amzn.to/3klmrQ9&#34;&gt;Thinking In Systems&lt;/a&gt; Donella Meadows observed that when maintaining a system the properties you can choose to optimize for include productivity, stability, and resiliency. Productivity is about producing outputs – for a software team this might be completed projects, fixed bugs, or releases shipped. Stability is about consistency of output; can you maintain the same level of productivity over time? Resilience is the property of being able to recover from perturbations and unexpected changes. For a software team that might mean being able to handle losing a teammate, adapt to remote work or maintaining productivity during a tumultuous time for an organization.&lt;/p&gt;
&lt;p&gt;Meadow’s interesting observation was that because resilience is less observable than productivity or stability, people tend to systematically underinvest in it. We can see outputs go up, and we can measure how they change over time, but resilience is by definition about response to rare and unexpected events, and therefore is hard to measure in normal circumstances. But the last year has been a reminder for many just how important resilience is; whether dealing with moving teams to remote work, &lt;a href=&#34;https://www.theatlantic.com/ideas/archive/2021/10/great-resignation-accelerating/620382/?utm_campaign=Herding%20Lions&amp;amp;utm_medium=email&amp;amp;utm_source=Revue%20newsletter&#34;&gt;the great resignation&lt;/a&gt;, supporting parents whose kids were suddenly home with them during the day, or the trauma of illness or loss from the pandemic, we’ve all had to deal with out of the ordinary circumstances when leading teams this year.&lt;/p&gt;
&lt;p&gt;So how do we cultivate resilience on our teams? Here are a few things I’m thinking about:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Reduce Work In Progress&lt;/strong&gt; - In addition to other benefits, reducing the # of things you’re working on a time helps team be more resilient by encouraging collaboration / shared knowledge.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Leave Margin&lt;/strong&gt; - Don’t fill 100% of your sprint/quarter/annual planning with roadmap projects. Leave meaningful slack that can be used on technical improvements, unplanned requests, maintenance and learning tasks. That work is valuable to start with but the margin that planning for it provides also can make your team more resilient to changes in plan or scope creep surprises.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Build Psychological Safety&lt;/strong&gt; - Teams that trust each other and can talk about difficult things are less likely to have issues fester and explode, and are more able to weather storms. Building a safe environment is the right thing to do for your teammates regardless of effectiveness, but the business case here is also easy to make.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Prioritize Developer Tooling &amp;amp; Velocity&lt;/strong&gt; - Its easy to adjust to change when you can move fast. Velocity makes everything easier, and great tooling also makes it easier to onboard new team members and reduces reliance on the head-canon context of your more experienced team members.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hire and Train For Redundancy In Your Team&lt;/strong&gt; - Teams of specialists lack resiliency. If only one person can do a particular task, then you’re vulnerable to anything that removes that person: leaving for a new job, an illness, a vacation, or just an opportunity for them to be promoted into new responsibilities.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Have Everybody Take Real Vacations&lt;/strong&gt; - Vacations are good for your team, but when people truly take the time off they’re also great “chaos engineering” experiments for your team to see how well you can function without different team members. If your output is limited when somebody is on vacation, it’s a smell that you can try and correct with some of the other tactics here.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rotate Responsibilities&lt;/strong&gt; - Similar to the last 2 items, we can build redundancy by making sure that we don’t rely on a single person to always fulfill certain tasks. It’s great to have experts and “owners” but those titles shouldn’t be exclusive and part of the responsibility should be helping others do the work and grow into co-owners.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Give Everyone Context&lt;/strong&gt; - When everybody understands the why behind a team’s work, it’s easier to adapt to changing conditions because that can happen throughout the team – the leader doesn’t need to understand every change or detail&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Write Documentation&lt;/strong&gt; - Another way to make it easier to ramp people up or move people between roles is to write things down. This means processes, architecture, how-tos. Thoughtful, well-maintained docs can add significant resilience to a team. Unfortunately this item is also the one that I’ve never really seen done well at a team level and may in practice be unrealistic. At an org level though this is extremely important for resilience.&lt;/li&gt;
&lt;/ol&gt;
</description>
    </item>
    
    <item>
      <title>Good Meetings Are Designed Not Born</title>
      <link>https://benmccormick.org/2021/11/02/190000.html</link>
      <pubDate>Tue, 02 Nov 2021 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2021/11/03/190000.html</guid>
      <description>&lt;p&gt;&lt;em&gt;This article was first published in my newsletter, &lt;a href=&#34;https://herdinglions.benmccormick.org/&#34;&gt;Herding Lions&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;There’s something deeply human about wanting to excel at the work we find ourselves doing. When we aspire to be effective at our jobs, how we describe and understand the key concepts in our work matters a lot. Last week &lt;a href=&#34;https://benmccormick.org/2021/10/27/team-output-productivity&#34;&gt;I talked about having a better model for productivity&lt;/a&gt; — measuring productivity at the team rather than the individual level can cause significant change in what we choose to work on and the environment we create for our teammates. This week I want to consider the beliefs we have around meetings. Do you believe that bad meetings are just an inevitable cost of the working world that we all must endure? Or can we work to create better meetings?&lt;/p&gt;
&lt;p&gt;I didn’t think very much about meetings early in my career; I just showed up where I was told, when I was told. Sometimes meetings were interesting, sometimes I just sat and waited for them to be over. For the especially long and irrelevant meetings, I learned that people didn’t object to me “taking notes” on my laptop, and I soon learned how to tune out without anyone caring.&lt;/p&gt;
&lt;p&gt;As I moved into the startup world and began to care more about my work though, I started to get into more meetings that were genuinely interesting to me, and bad meetings started to bother me more. When I began learning about management and taking more leadership, I read more about the theory behind meetings and started paying closer attention to what worked and didn’t in meetings. What I learned is that good meetings are designed, not born. It’s possible to have meetings that are good experiences for everyone involved, but it takes intentionality.&lt;/p&gt;
&lt;p&gt;There are 4 levers I use when designing a meeting: choosing the audience, crafting the agenda, picking the right cadence, and shifting aspects async.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Audience&lt;/strong&gt; - Meetings without key decision makers or subject matter experts often end without conclusions, and decisions can get overturned quickly afterwards. On the flip side, while it may feel kind to invite anyone interested to a meeting, a meeting with too many people can become chaotic, waste people’s time, or stifle contribution if some people aren’t comfortable being open and honest in front of the full group for reasons of timidity, confidentiality, or simply unfamiliarity with the participants.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Agenda&lt;/strong&gt;- Coming into a meeting with a clear agenda doesn’t always lead to a great experience, but without one it’s pretty much impossible to guarantee a well run meeting. A thoughtful agenda sets a direction for a meeting, makes goals clear and helps people prepare. Written agendas are great, but a simple verbal “the goal for this meeting is” at the beginning of a less formal meeting can go a long way. It’s never too late to reset everybody towards a plan.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Cadence&lt;/strong&gt; - Should a meeting occur daily? Weekly? Monthly? On an as needed / ad hoc basis? This decision has a big impact on a meetings tone and impact. Set this too regularly and you’ll find you’re wasting people’s time and losing engagement. Too spread apart and you might not really be accomplishing your goals.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Async&lt;/strong&gt; - We’ve all been in a classic “could have been an email” meeting. But even for meetings that clearly do merit time together, it’s worth asking if parts of it can be split out async. Maybe updates can go into Slack while we meet to talk about strategic discussions or open problems. Maybe instead of demoing a new design and then discussing it in a meeting, a designer could send a video of the design, take some async comments and then meet to discuss the more controversial aspects of the design that weren’t fleshed out in comments.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The process for designing a meeting with these levers is straightforward. Break down what needs to be accomplished (goals), identify the audience for each goal, consider whether a goal can be fully or partially accomplished async, figure out the cadence for the meeting(s), and then write an agenda for each meeting you’re creating.&lt;/p&gt;
&lt;p&gt;My single most important meeting design advice is never start with a meeting, start with your goals. Some of the worst meetings are those that try to do 5 things poorly rather than 1 or 2 things well. When you start by breaking down and defining what you want to accomplish, it becomes much easier to pick the right audience, agenda and cadence for your goals. For instance I was recently part of a weekly cross-org meeting that was attempting to push forward tactical code level changes as well as serve as an announcement/discussion place for important strategic announcements. Attendance was poor and the meetings were often low on engagement. The organizers were able to greatly improve this meeting by identifying and breaking apart these goals, shifting to 2 meetings: a monthly strategic meetings for managers and a weekly tactical meeting for engineers involved in the initiatives.&lt;/p&gt;
&lt;p&gt;Once you have a set of goals, you should figure out the audience for each one. If the audiences of your goals are sufficiently different, consider splitting your goals across multiple meetings or async mediums rather than trying to cram them into a single meeting. Even if it feels inefficient for you as an organizer, it can greatly streamline the process and bring better outcomes for everyone as in the above example. If your goals all need roughly the same audience, just think carefully about who really needs to be included. There’s a lot of value in keeping information open, sponsoring folks for opportunities, and listening to all voices. However there’s a delicate balance between pursuing those goals and inviting chaos or wasting people’s time. If you’re having trouble cutting a meeting, consider inviting a smaller group but sending the minutes to a larger one to keep them in the loop, or workshopping a proposal with a small group and then presenting it to a different group of stakeholders.&lt;/p&gt;
&lt;p&gt;At this point you should be able to see if you really need a meeting or whether your goals can be accomplished async, and what their cadence should be. Sometimes some goals may need a meeting while others can be handled async. For instance when we redesigned my team’s standups last year we determined that our “individual status updates” could be handled async through Slack, and the purpose of our standup Zooms would be connecting as a team, checking in on project status with a quick confidence check and an open floor for people to discuss issues and blockers. This allowed us to remove some boilerplate from the meeting discussion, honored my team’s desire to have more dedicated “team time” during the pandemic, and led to deeper and more relevant discussions. When in doubt I recommend starting with something happening async until it proves that it needs a meeting. If you do believe you need to meet in person consider starting with meetings scheduled on a case by case basis rather than immediately jumping into a recurring cadence. You’ll get a sense of how often the meeting is relevant.&lt;/p&gt;
&lt;p&gt;Finally, make sure to have an agenda. If you’ve started with goals this is easier. Each goal covered by a meeting should be an agenda item. I’m currently running a daily project check in sync where we determined the goals were to make sure we stayed on track, make sure we were working tightly together across roles, and quickly resolve blockers as they arose. As a result the agenda for that meeting is a 2 minute review of our progress against project tickets in Jira, an open time for developers and our designer to demo any new updates to the team as they complete work, and then a period for raising blockers or issues for the team to discuss and hopefully resolve. Each section of the meeting is directly connected to a goal so the agenda was easy to write. For one off or informal meetings you may not have a written agenda, but I still recommend that you call out the goals as you start the meeting, and circle back at the end to make sure you’ve addressed each goal. This practice has made a big difference for me in terms of running effective meetings.&lt;/p&gt;
&lt;p&gt;The quality of a meeting isn’t the result of a dice roll. You can make a meeting better with planning. Take the time to do it.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>New Newsletter: Herding Lions</title>
      <link>https://benmccormick.org/2021/10/26/190000.html</link>
      <pubDate>Tue, 26 Oct 2021 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2021/10/27/190000.html</guid>
      <description>&lt;p&gt;This blog has always been a bit of an eclectic assortment of topics that have reflected my shifting interests over time.  Recently I&amp;rsquo;ve been &lt;em&gt;primarily&lt;/em&gt; interested in writing about Engineering Management, my role for the last 3.5 years.  I&amp;rsquo;ve also been craving more conversation on these topics and want to be more interactive in my writing.&lt;/p&gt;
&lt;p&gt;As an experiment towards those 2 goals, I&amp;rsquo;m starting a new newsletter &lt;a href=&#34;https://herdinglions.benmccormick.org&#34;&gt;Herding Lions&lt;/a&gt; focused on Engineering Management.  It will have a mix of shorter pieces from me, interesting links, and questions that I&amp;rsquo;m hoping to engage with folks on. I&amp;rsquo;m excited to hear from you there.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://herdinglions.benmccormick.org/issues/herding-lions-1-team-output-is-the-smallest-unit-of-productivity-828140&#34;&gt;You can see the first issue and subscribe here&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Thinking Fast &amp; Slow: Lessons For Managers</title>
      <link>https://benmccormick.org/2021/10/20/190000.html</link>
      <pubDate>Wed, 20 Oct 2021 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2021/10/21/190000.html</guid>
      <description>&lt;p&gt;I recently read &lt;a href=&#34;https://amzn.to/3jpFxUJ&#34;&gt;Thinking Fast &amp;amp; Slow&lt;/a&gt; by Daniel Kahneman, and it was my favorite read of this year.  I had been generally familiar with Behavioral Economics previously, but this was the deepest I&amp;rsquo;d gotten into it.  Kahneman is a very strong writer, and it left me with lots of things to think about.  A few of the ideas in particular felt relevant to management, and I thought I&amp;rsquo;d highlight them here.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Everybody thinks about their lives and careers as a story.  When we evaluate how good a story it is we tend to think about the high points, low points and most recent feelings &lt;em&gt;only&lt;/em&gt;, neglecting how long any of those things lasted. [Summarized from the chapter 36 &amp;ldquo;Life as a Story&amp;rdquo;]&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This made me think of how a bad week, or a very bad incident in the past can negatively color the story of an employee with an otherwise happy tenure leading to what Michael Lopp calls &lt;a href=&#34;https://randsinrepose.com/archives/shields-down/&#34;&gt;shields down&lt;/a&gt; moments.  This can feel unfair for managers who are doing things right and want to maintain their teams, but the main lesson I take is to not let little annoyances fester without addressing them, as little things can shift people&amp;rsquo;s attitudes by more than is justified by a big picture view.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Humans have a number of cognitive traits that make us bad at predicting and estimating — we ignore evidence that is not currently on our mind, become confident on relatively small pieces of information, and have a tendency to simplify complexity away by answering easier questions than what we’ve been asked. We also over-weight “causal thinking” and underestimate regression to the mean. [Summarized from Chapters 18-24]&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This was easy enough to accept personally &amp;ndash; I&amp;rsquo;m perennially overconfident in my estimates.  The lesson here in my mind is that more process around predictions may lead to better outcomes; left to our own devices we&amp;rsquo;ll think less about predictions and not notice that our confidence is based on flimsy evidence.  For more important predictions, processes that force us to be more thorough should help.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Humans are very sensitive to how questions are framed — we hate losing things more than we like gaining them, are very associative in our thinking, and often aren’t consistent in how we make choices depending on external factors like a suggested answer, another question we were just asked, or how close it is to a meal.  [Summarized from Chapters 25-34]&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I see this type of stuff in behavioral economics mostly quoted in terms of &amp;ldquo;nudge&amp;rdquo; like behavioral manipulation, but this mostly has me thinking about the importance of communication plans.  It&amp;rsquo;s easy to think that getting info passed to a team or individual is more important than how you do it, but actually how choices and changes are communicated has a real impact on how people feel about them, which can make a big difference to team morale and retention over the course of many communication opportunities. Lara Hogan has some good resources on communication plans including &lt;a href=&#34;https://larahogan.me/blog/communicating-news-to-team/&#34;&gt;this article&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;We all overweight things that are easy for us to see vs things that are not (availability bias).  We tend to see our own contributions as bigger and more meaningful than others, our own challenges as more painful, and our own skills as more impressive.  Because of course we see all the evidence for those and only a fraction of what others are doing. [Summarized from Chapter 12 and some references elsewhere]&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This was a good reminder to me to be humble and not overweight my own accomplishments first.  But it also is a good thing to keep in mind the next time a teammate feels underappreciated or that they may have been unfairly passed up for an opportunity.  We&amp;rsquo;re all prisoners of our own perspectives, and while that may sometimes lead us astray in terms of how we stack up a little grace can go a long way here.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Kustomer Is Hiring</title>
      <link>https://benmccormick.org/2021/09/22/190000.html</link>
      <pubDate>Wed, 22 Sep 2021 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2021/09/23/190000.html</guid>
      <description>&lt;p&gt;👋 Hi There!&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s been a bit of a quiet year on the blog as I&amp;rsquo;ve been figuring out life with 2 children, work and a pandemic that doesn&amp;rsquo;t seem like it wants to go away.  I&amp;rsquo;m going to try writing a bit more soon, but in the meantime wanted to add a quick plug for &lt;a href=&#34;https://www.kustomer.com/&#34;&gt;Kustomer&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve had the pleasure of working at Kustomer the past 2 years now &amp;ndash; it&amp;rsquo;s been a crazy rocket ship experience, my first time in a high growth unicorn startup, and we&amp;rsquo;re very much &lt;em&gt;just getting started&lt;/em&gt; in many ways &amp;ndash; we&amp;rsquo;re looking forward to &lt;a href=&#34;https://about.fb.com/news/2020/11/kustomer-to-join-facebook/&#34;&gt;joining Facebook&lt;/a&gt; in the future and all the possibilities that will bring to the table.&lt;/p&gt;
&lt;p&gt;In the here and now though, we&amp;rsquo;re building an extremely cool product &amp;ndash; improving customer service experiences for millions of people by giving agents better info and better tools and making it easier for people to find the info they want themselves without long hold times or delays between emails. We&amp;rsquo;ve got lots of fun technical challenges as we scale  and work to improve performance of our system at every level (you can get a taste of a few of these at the recently started  &lt;a href=&#34;https://medium.com/kustomerengineering&#34;&gt;Kustomer Engineering blog&lt;/a&gt;).  And we have a fantastic team of engineers who are extremely collaborative and focused on building the best experience for our customers (and their customers).&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;re growing like crazy and have a ton of ambitious plans for the future, which means we need more folks.  We&amp;rsquo;re hiring for&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://grnh.se/310f16421us&#34;&gt;Engineering Managers&lt;/a&gt;: EMs at Kustomer get to lead 1 to 2 teams of 3-7 engineers each of which have a specific product focus.  You get to wear a lot of hats &amp;ndash; technical leader, domain expert, coach, chaos-tamer, and are pretty much guaranteed to learn a lot.  My 2 years in this role has not always been easy, but it has pushed me to grow more than any other stretch in my career. It&amp;rsquo;s a great role for people who like a challenge and thrive on taking on different types of work depending on the day.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://grnh.se/5765189b1us&#34;&gt;Frontend Engineers&lt;/a&gt; at Kustomer get a large amount of autonomy to solve business and user experience problems in their domain of expertise.  Every team has a dedicated Product Manager and Designer that you&amp;rsquo;ll be collaborating closely with, and we&amp;rsquo;re at a fun point in our growth where we&amp;rsquo;re taking a product that has grown organically and finding ways to standardize best practices, improve performance, and be more consistent in building great user experiences, not just &amp;ldquo;working&amp;rdquo; experiences.  It adds up to a lot of great technical challenges, and we&amp;rsquo;re big enough to have experienced engineers to support and teach while still being small enough to have lots of room for people to come in and own important problems.  Our core stack is React / Redux / TypeScript / Jest / Cypress / Webpack.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://grnh.se/3fe8d8871us&#34;&gt;Backend Engineers&lt;/a&gt; have similar collaborative and ownership opportunities as FE devs, and get to work in a modern Node microservice based codebase with its own set of interesting technical challenges, especially as we scale the product.  We spend a lot of time thinking about reliable message processing, storing and performantly accessing large amounts of data, and applying machine learning and intelligent automation techniques to customer service data.  Our core stack is Node / Express / Docker / ECS / AWS / MongoDB / ElasticSearch.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;*All of these roles will eventually be New York City based, but are currently operating remotely.  *&lt;/p&gt;
&lt;p&gt;If any of the above roles sound like the right type of challenge for you please feel free to reach out and apply.  You&amp;rsquo;re also welcome to &lt;a href=&#34;mailto:ben@kustomer.com&#34;&gt;contact me&lt;/a&gt; with any questions about working at Kustomer.  Helping bring new awesome people who are excited about what we&amp;rsquo;re doing into the company is the most important thing I can do both for them, for Kustomer and for making my own job great, so always happy to talk.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Engineering Management: How To Give Feedback</title>
      <link>https://benmccormick.org/2021/03/06/190000.html</link>
      <pubDate>Sat, 06 Mar 2021 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2021/03/07/190000.html</guid>
      <description>&lt;p&gt;&lt;em&gt;I&amp;rsquo;m currently taking some time away from my job on parental leave, and it seemed like a good time to reflect on the lessons I&amp;rsquo;ve learned the last few years about engineering management. This is my fifth post, you can see a list of past posts on the &lt;a href=&#34;https://benmccormick.org/engineering-management-thoughts&#34;&gt;series page&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Giving good feedback to others is a core piece of any manager&amp;rsquo;s job, but it&amp;rsquo;s also one that is rarely taught formally.  We all give feedback in some form or other every day: we leave reviews, give compliments, complain, or thank people.  But making the feedback effective is a lot harder, and as a manager it is well worth the effort to consider how you can improve.  Let&amp;rsquo;s talk about the why, when and how of effective feedback.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The majority of people-related disasters I’ve created originate with my choice to not say the hard thing. On my short list of critical leadership skills, the ability to “say the hard thing” is right after “delegate until it hurts.” - &lt;a href=&#34;https://randsinrepose.com/archives/say-the-hard-thing/&#34;&gt;Michael Lopp&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;As managers we give feedback because it is &lt;strong&gt;the core way we drive improvement&lt;/strong&gt;.  We are not generally &lt;em&gt;doing the work&lt;/em&gt;, instead we &lt;em&gt;evaluate the work&lt;/em&gt; and give feedback.  That means making it clear to the team when we see things that are or are not working with the end product, the process to build that product or the inner dynamics of the team.  And it means being clear with individuals what is or isn&amp;rsquo;t working.  Improvement for teams and individuals is a function of practicing the relevant tasks over time with useful feedback loops.  Teams will get some natural feedback loops from the result of their work, peer feedback, and self evaluation but those are unreliable and/or slow.  As a manager you are responsible for making sure that your teammates have tight feedback loops that allow them to understand quickly when things are going off track and correct them, or when they are doing something well and have an opportunity to do even more.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“if it hurts, do it more often, and bring the pain forward.” - &lt;a href=&#34;https://amzn.to/2PFTySp&#34;&gt;Continuous Delivery&lt;/a&gt; by Jez Humble and David Farley&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It&amp;rsquo;s important to understand that feedback isn&amp;rsquo;t something that should happen only at performance reviews &amp;ndash; &lt;strong&gt;good feedback is continuous&lt;/strong&gt;.  It&amp;rsquo;s helpful to have regular times for giving and soliciting feedback like a weekly 1-1, but even those should be a backstop &amp;ndash; giving feedback directly after you observe a behavior or impact is often the best time.  We want to minimize the &lt;em&gt;feedback loop&lt;/em&gt; so that your teammate can respond quickly, and also minimize distance from the event which can often bring skewed memories from both parties.  For those who find giving feedback hard or scary, the idea of doing this regularly might seem overwhelming.  In this case though we can benefit from the devops principle of doing hard things more often.  When feedback is regular and low intensity it can be easier to give and absorb, whereas a mountain of feedback at a performance review can be overwhelming and scary to give.  Early feedback also allows for quicker course correction, hopefully making those difficult review conversations less common.  Performance reviews should never contain surprises, they should just be formalization of an ongoing conversation.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;Radical Candor&amp;rdquo; is what happens when you put &amp;ldquo;Care Personally&amp;rdquo; and &amp;ldquo;Challenge Directly&amp;rdquo; together - &lt;a href=&#34;https://amzn.to/3sVHLh2&#34;&gt;Radical Candor by Kim Scott&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&#34;https://amzn.to/3sVHLh2&#34;&gt;Radical Candor&lt;/a&gt; has influenced my thoughts on feedback more than any other single source, and while the book is worth reading in full, its core idea is easy to summarize: &lt;strong&gt;good feedback comes from caring personally about the individual and being willing to challenge them directly&lt;/strong&gt;.  We&amp;rsquo;ve all dealt with the jerk who is happy to give unfeeling and unwelcome feedback on anything &amp;ndash; that&amp;rsquo;s challenging without caring, what Kim Scott calls &amp;ldquo;obnoxious agression&amp;rdquo; in the book.  More common and insiduous though is what she calls &amp;ldquo;ruinous empathy&amp;rdquo; and &amp;ldquo;manipulative insincerity&amp;rdquo; &amp;ndash; caring or not caring without challenging and thus simply avoiding feedback altogether.  The single biggest antipattern around feedback that I&amp;rsquo;ve seen is choosing to not give it until it is much too late.  People who give good feedback have plenty of empathy and understand the impact of their words &amp;ndash; but they also understand how people can be hurt when nobody tells them the truth, so they let that empathy drive them to choose their words carefully and judiciously speak out with courage.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The Situation-Behavior-Impact method is simple and direct: You capture and clarify the Situation, describe the specific Behaviors observed, and explain the Impact that the person’s behavior had on you. &lt;a href=&#34;https://www.ccl.org/articles/leading-effectively-articles/closing-the-gap-between-intent-and-impact/&#34;&gt;Center For Creative Leadership&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If you&amp;rsquo;re struggling with how to express a certain piece of feedback it can be helpful to prepare in advance.  I usually benefit from writing down my thoughts and have found the SBI method from the Center For Creative Leadership very helpful here.  &lt;strong&gt;For any feedback you want to give, frame it in terms of the situation (when and where did this happen &amp;ndash; any relevant context), the behavior you observed from the person receiving the feedback (what did they do), and the impact on you or that you observed&lt;/strong&gt;.  This model is helpful in giving a clear way to write feedback as well as avoiding a bunch of potential traps.  It leads you away from guessing at anyone&amp;rsquo;s intent or motivations, grounds the feedback in a real situation and behavior, and makes the severity of the feedback clear.  Optionally you can continue to a 4th step &amp;ndash; asking the person receiving the feedback what their intention was and giving them a chance to share their thoughts, hopefully leading to a productive 2 way conversation.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Feedback is a gift - &lt;a href=&#34;https://marcusblankenship.com/the-art-of-leadership-with-michael-lopp/#:~:text=Feedback%20is%20a%20gift.&#34;&gt;Michael Lopp&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So far in this piece I&amp;rsquo;ve focused on giving feedback, but it&amp;rsquo;s important to remember that feedback is a two way street.  &lt;strong&gt;Giving feedback well gets easier when we develop an attitude of curiousity and gratitude when we receive feedback.&lt;/strong&gt; Remember that all feedback is a gift &amp;ndash; even if some pieces of feedback are easier to work with and better delivered than others.  Creating an environment where others are comfortable giving you feedback is hard &amp;ndash; if you&amp;rsquo;re a manager you will have to work upstream to overcome some natural power dynamics if you want real honest feedback.  It means being persistent in asking over time, building trust by proving you care, and being willing to take and be grateful for hard feedback when it does come.  Ultimately there is almost nothing you can do that will help you more as a manager than creating an attitude where people are comfortable sharing unfiltered truth with you &amp;ndash; you&amp;rsquo;ll grow faster and be more effective as you learn what is really happening around you, and it is much easier to share hard feedback with people who trust that you&amp;rsquo;re listening to them.  Feedback is a gift.  Give it, receive it and value it.&lt;/p&gt;
&lt;h3 id=&#34;more-engineering-management-posts&#34;&gt;More Engineering Management Posts&lt;/h3&gt;
&lt;p&gt;This is part of a series of posts on Engineering Management.  You can see the whole series &lt;a href=&#34;https://benmccormick.org/engineering-management-thoughts&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Engineering Management: How To Delegate</title>
      <link>https://benmccormick.org/2021/02/25/190000.html</link>
      <pubDate>Thu, 25 Feb 2021 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2021/02/26/190000.html</guid>
      <description>&lt;p&gt;&lt;em&gt;I&amp;rsquo;m currently taking some time away from my job on parental leave, and it seemed like a good time to reflect on the lessons I&amp;rsquo;ve learned the last few years about engineering management. This is my fourth post, you can see a list of past posts on the &lt;a href=&#34;https://benmccormick.org/engineering-management-thoughts&#34;&gt;series page&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;In my &lt;a href=&#34;https://benmccormick.org/2021/02/23/ems-handling-accountability&#34;&gt;last post&lt;/a&gt; I discussed the importance of delegating work to your team and giving them room to do important work.  Delegation like this is crucial for effective managers, it&amp;rsquo;s the only way that you&amp;rsquo;ll ever have time to grow and it&amp;rsquo;s the only way that you can help your team grow.  But it isn&amp;rsquo;t always easy, and effective delegation certainly isn&amp;rsquo;t as simple as giving somebody a task and walking away.  I&amp;rsquo;ve picked up a few principles over time on how to delegate well, as well as a few practices that have been helpful for me in finding the right mix of delegation. The principles that have been most helpful for me when delegating work have been to &amp;ldquo;trust by default&amp;rdquo;, thinking about people&amp;rsquo;s ability in terms of &amp;ldquo;task relevant maturity&amp;rdquo;, &amp;ldquo;not being essential&amp;rdquo;, and &amp;ldquo;giving objectives and context rather than just tasks&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;The most important step to beginning delegation is to &lt;strong&gt;trust by default&lt;/strong&gt; rather than making people prove themselves before giving them opportunities.  Trusting in this context doesn&amp;rsquo;t mean blindly handing people arbitrarty work and expecting it to go well.  But it means being willing to give people reasonable stretch opportunities and then properly supporting them through them, and doing that starting early on in your management relationship with them.  Ideally trust will build as you work with a teammate, but if you default to a &amp;ldquo;prove it&amp;rdquo; attitude it can be tough for teammates to ever gain your trust.  If this proves difficult for you it may point to a higher level problem like you being too attached to doing work yourself or not having the right people on your team for the work you&amp;rsquo;re trying to accomplish.  Don&amp;rsquo;t jump to that last conclusion though &amp;ndash; it&amp;rsquo;s important to look in the mirror first.&lt;/p&gt;
&lt;p&gt;When evaluating people&amp;rsquo;s ability to handle a task you&amp;rsquo;re considering delegating to them, you shouldn&amp;rsquo;t be looking at their title or general track record, but instead focusing on what Andy Grove calls their &lt;strong&gt;task relevant maturity&lt;/strong&gt; &amp;ndash; how experienced they are at the specific task under discussion.  It&amp;rsquo;s possible to give brand new employees tasks that are easily within their wheelhouse and very senior team members tasks that are outside of anything they&amp;rsquo;ve done before.  If you base your support and expectations solely on how senior somebody is or how successfully they&amp;rsquo;ve handled generic delegated work in the past, you&amp;rsquo;re likely to mishandle the delegation.&lt;/p&gt;
&lt;p&gt;Adjusting well based on task relevant maturity means giving teammates who have less experience of success with a task more support and monitoring their progress more frequently.  This doesn&amp;rsquo;t mean micro-managing, but being a resource to the employee, checking in on the task regularly during 1-1s and reviewing any incremental steps in the process for signs that you&amp;rsquo;ve become misaligned on the objective or that things are off track.  The key is that you&amp;rsquo;re a support resource and a quality checker, not laying down specific restrictions on how the task is done.  For teammates with progressively more experience with the task you can reduce check-ins and explicit offers of support to match their comfort level, though you should never completely ignore projects or lose track of what is going on with anything important.&lt;/p&gt;
&lt;p&gt;A 3rd principle of delegation is more a warning post that you&amp;rsquo;re not delegating enough.  &lt;strong&gt;I never want to be essential&lt;/strong&gt; for any task as a manager.  If I get hit by a bus or leave the company, my ideal is that everything in the teams reporting to me will hum along perfectly for a long time, with my absence being felt only in lost potential in how I could have helped people grow, or solved higher level problems in the company.  That means that if I see areas where I am &lt;em&gt;essential&lt;/em&gt; for success, rather than allowing that to inflate my self importance I should view it as a sign that I need to grow somebody on my team into that role.  If there are people who could be doing it but I&amp;rsquo;m not giving them the opportunity, it&amp;rsquo;s time to delegate.  If there&amp;rsquo;s nobody who can do the work, then it&amp;rsquo;s a gap on the team that needs to be filled by training or hiring.&lt;/p&gt;
&lt;p&gt;Finally, it&amp;rsquo;s important to delegate at the right level.  Delegating completely defined tasks with a prescribed solution is just asynchronous micro-managing.  Instead you should &lt;strong&gt;delegate objectives, and give people the context they need to make good decisions&lt;/strong&gt;. For technical work this can come through in how a Jira ticket or Github issue is written.  Does it describe a technical change that needs to be made without explaining why?  Or does it describe a user problem, with context around what we know about past attempts to solve it or any relevant constraints&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;?  When having a tech lead replace them in an interview, a manager could choose to give them the list of questions they have been asking and ask the tech lead to read from the sheet, or they could explain what they&amp;rsquo;re looking for in the position, any constraints around what will be accepted by the wider organization, and then have a discussion around the interview questions that the tech lead might want to use.  The second way will engage the tech lead&amp;rsquo;s brain, give them ownership and maybe help the manager learn something.&lt;/p&gt;
&lt;h3 id=&#34;practical-activities-to-delegate-better&#34;&gt;Practical Activities To Delegate Better&lt;/h3&gt;
&lt;p&gt;It&amp;rsquo;s good to understand the principles and theory behind delegation, but what if you&amp;rsquo;re not getting it right in practice?  When I discovered last year that I was not delegating nearly enough, there were 2 activities I went through that helped me do a better job with this: a weekly review and being extra explicit about ownership&lt;/p&gt;
&lt;p&gt;After getting feedback from multiple folks that I was trying to do too much work myself, my first step to getting better was a simple 30 minute &lt;strong&gt;weekly review&lt;/strong&gt; where I went through all of my activities from the week and listed out anything I&amp;rsquo;d spent time on that wasn&amp;rsquo;t part of what I considered my &amp;ldquo;core responsibilities&amp;rdquo;.  From that first list I then considered 2 questions: who else could be doing this work, and are there good reasons why I&amp;rsquo;m doing it instead?  If you&amp;rsquo;ve never thought this through before you may find some good low hanging fruit where you&amp;rsquo;re doing work that somebody else on your team would benefit from doing without a compelling reason.  It&amp;rsquo;s perfectly fine if many of the things on this list are more complicated though.  There may not be an obvious person for every piece of work, or there may be good reasons why you&amp;rsquo;re picking it up.  In those cases the goal of the exercise is to bring clarity and give you time to think about what would need to happen to move these tasks to a teammate who would benefit from the work and/or be a more appropriate fit.  Maybe you need to invest in coaching a teammate, have a difficult conversation with a peer about ownership, or just need to document the work so that other people can do it.&lt;/p&gt;
&lt;p&gt;I started this exercise focused on &amp;ldquo;non-core&amp;rdquo; work, but scaling yourself as an EM means constantly giving up work and letting others grow into it.  So feel free to consider all of your responsibilities and see if there&amp;rsquo;s an opportunity for others to grow into some of those while you grow into broader and new opportunities or just get more time back to invest in people.&lt;/p&gt;
&lt;p&gt;Another thing I found helpful when starting to document more was &lt;strong&gt;being explicit about ownership&lt;/strong&gt;.  If you have been handling a type of task yourself and want others to step into it, there are benefits to creating a clearly defined role or set of work that you can give somebody.  Without this it can be easy for some piece of the work to fall back to you or be missed.  For instance if you&amp;rsquo;ve been doing most of the project management on tech projects and want engineers to step into that, it might be helpful to create and document a &amp;ldquo;project tech lead&amp;rdquo; position that you assign for each project.  You can then be explicit that the project tech lead is responsible for keeping the project on schedule and identifying or escalating threats to the project plan along with any other duties that make sense.  You can also be explicit about what ways you expect to be supporting a project tech lead and any responsibilities that still fall on you as an EM.&lt;/p&gt;
&lt;h3 id=&#34;why-delegate&#34;&gt;Why Delegate?&lt;/h3&gt;
&lt;p&gt;Delegating work well is an incredibly rewarding activity.  You give others opportunities to grow.  You can reduce your own stress and increase your capacity.  You&amp;rsquo;ll learn from seeing other people take different approaches to work you have done in the past.  Over time this will help create a team that is excited about their work since they&amp;rsquo;re empowered to do meaningful work and continue growing over time, and it will allow you to continue tackling new challenges as well.  So take some time today to figure out where you can find new places to share your opportunities and create new ones.&lt;/p&gt;
&lt;h3 id=&#34;more-engineering-management-posts&#34;&gt;More Engineering Management Posts&lt;/h3&gt;
&lt;p&gt;This is part of a series of posts on Engineering Management.  You can see the whole series &lt;a href=&#34;https://benmccormick.org/engineering-management-thoughts&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;To be clear it certainly makes sense to sometimes put more &amp;ldquo;do this technical thing&amp;rdquo; type tasks into an issue tracker and assign them to people.  But the developers doing the work should be part of the process of designing that solution before it got assigned to them.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>Engineering Management: Handling Accountability</title>
      <link>https://benmccormick.org/2021/02/22/190000.html</link>
      <pubDate>Mon, 22 Feb 2021 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2021/02/23/190000.html</guid>
      <description>&lt;p&gt;&lt;em&gt;I&amp;rsquo;m currently taking some time away from my job on parental leave, and it seemed like a good time to reflect on the lessons I&amp;rsquo;ve learned the last few years about engineering management, this is my third post, you can see a list of past posts on the &lt;a href=&#34;https://benmccormick.org/engineering-management-thoughts&#34;&gt;series page&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;When moving into an engineering manager role, one of the toughest transitions for me was mentally adjusting from being responsible for tasks and projects that I owned to being accountable for the output of a team.  As I discussed in &lt;a href=&#34;https://benmccormick.org/2021/02/18/what-do-ems-do&#34;&gt;What Engineering Managers Do&lt;/a&gt;, I like using Andy Grove&amp;rsquo;s definition of a manager&amp;rsquo;s output: the output of their team as well as the output of any teams that they&amp;rsquo;re influencing.  Manager&amp;rsquo;s thus bring value by improving those outputs.  This potentially allows you as a manager to have a much larger sphere of impact than an individual contributor working on a single project at a time.  But it also means that you will be held accountable for actions that you may not have had direct control over.  This can be distressing for new EMs (it was for me!) as you realize that &amp;ldquo;working harder when things go wrong&amp;rdquo; may no longer be a viable strategy for avoiding failures.&lt;/p&gt;
&lt;p&gt;The first time a manager gets negative feedback for work that wasn&amp;rsquo;t personally in their control it is tempting to prevent it in the future by micromanaging or using themselves as a safety net.  Micromanaging has a horrible reputation, but it is actually a very natural reaction for engineers who are used to competently completing tasks and then being praised for it who face criticism when a task they know they could complete is not done adequately.  It is a very human response at this point to say &amp;ldquo;well I know how to do that, let&amp;rsquo;s make sure you&amp;rsquo;re doing it the way I would&amp;rdquo;.  When that is repeated over time it leads to the familiar and awful rhythm of low trust between the manager and teammate, low initiative from the teammate and frustratingly slow progress.&lt;/p&gt;
&lt;p&gt;Acting as a safety net for employees is a more subtle task for managers.  They may know they don&amp;rsquo;t want to micromanage, but instead they might choose to tackle the complex, likely-to-fail parts of a task themselves, or perform a &amp;ldquo;diving save&amp;rdquo; taking over a project when it looks like it might not complete successfully.  This appears better than micro-management &amp;ndash; employees have ownership of their work, at least until it goes off the rails.  But it leads to many of the same issues as pure micromanagement: employees who don&amp;rsquo;t grow because they&amp;rsquo;re not learning to do the hard work themselves, a disconnection from consequences that means a lack of ownership from the team, and a lack of trust that will eventually erode morale.  Like micromanagement though, this approach doesn&amp;rsquo;t scale.  You and your team will both be locked to a limited amount of responsibility that is based on your capacity as a manager to be in the details of everything.  Growing as a leader and a team requires a different approach.&lt;/p&gt;
&lt;p&gt;The only solution for handling accountability that scales is developing a high performing team.  It isn&amp;rsquo;t a problem to be held responsible for the output of a group that you trust and believe in.  And high performing teams have a tendency to generate new leaders, allowing you to do less and/or focus on higher level work and grow your career. But creating a team like that requires effort and humility over time.  This means as managers we have to be willing to take some short term failures.&lt;/p&gt;
&lt;p&gt;While your team is in a growth stage (any of the &lt;a href=&#34;https://en.wikipedia.org/wiki/Tuckman%27s_stages_of_group_development&#34;&gt;forming, storming, norming steps in a group&amp;rsquo;s development&lt;/a&gt;) you&amp;rsquo;ll need to expect that their output will not always meet your individual standards.  There are a few things you can do to mitigate this from an accountability perspective.&lt;/p&gt;
&lt;p&gt;Firstly it is important to match your expectation setting and commitments to your team&amp;rsquo;s maturity.  If you&amp;rsquo;re not confident that a team can make a commitment without you doing the work yourself, don&amp;rsquo;t sign on for the work.  And certainly try to limit the number of simultaneous challenging projects you&amp;rsquo;re taking on so that you can focus on enabling your team when you do have challenges.  This may sound naive and frustrating to people who feel they &lt;em&gt;have&lt;/em&gt; to take on the work.  The key thing to understand are that you can&amp;rsquo;t do this forever &amp;ndash; eventually the team has to grow it&amp;rsquo;s capacity to something the organization can accept, or either you or your management is failing.  But in most circumstances it&amp;rsquo;s better to give an honest no up front than make excuses for a failed project 3 months down the road.  There are organizations which won&amp;rsquo;t reward that calculus &amp;ndash; in which case you should probably document your concerns and continue anyway, hopefully developing some credibility for the next such discussion.&lt;/p&gt;
&lt;p&gt;When you&amp;rsquo;re in this type of growth stage, it&amp;rsquo;s also important to understand the impact of the work that is coming in.  I like the analogy that &lt;a href=&#34;https://davidnovakleadership.com/blog/crystal-vs-rubber/&#34;&gt;Gregg Dedrick shares here&lt;/a&gt; of juggling crystal and rubber balls.  Some tasks are like crystal balls &amp;ndash; if you drop them there are expensive consequences and no second chances.  But most tasks are more like rubber balls.  If you drop one you&amp;rsquo;ll get to pick it up and try again.  It&amp;rsquo;s important to understand which are which.  If your growing team is being asked to pick up crystal ball tasks it&amp;rsquo;s important to exercise caution.  This is where it&amp;rsquo;s extra important to be clear about your team&amp;rsquo;s capacity, and is a case where it may be appropriate to get more involved personally to ensure success.  Of course if most of the tasks coming your way seem like crystal balls, it&amp;rsquo;s worth digging into that more and understanding what is driving that, and if some of them are actually more droppable than you think.&lt;/p&gt;
&lt;p&gt;As your team grows you&amp;rsquo;ll be able to start shifting the work you take on and saying yes to more things.  At this point it&amp;rsquo;s important to nurture the ownership that your team is feeling.  Be generous with credit for successes while continuing to own accountability for failures.  Within the team, make sure you are holding high standards and giving clear feedback when needed.  Nothing undercuts an empowered team like somebody who isn&amp;rsquo;t contributing at the level of the rest of the team and isn&amp;rsquo;t held accountable for that.  That said, leave room for failures to continue happening.  Even high performing teams have room to grow, so the principles for a growing team still apply &amp;ndash; let people take on rubber ball tasks that are a stretch,&lt;/p&gt;
&lt;h2 id=&#34;accountability-for-a-high-performing-empowered-team&#34;&gt;Accountability for a high performing empowered team&lt;/h2&gt;
&lt;p&gt;Managing a team that feels ownership of their work and is growing into higher levels of capability is more rewarding, less stressful, more educational, and more powerful for your career than micromanaging.  It&amp;rsquo;s also ultimately morally good &amp;ndash; you&amp;rsquo;re creating an environment where other people can thrive and use their gifts and abilities.&lt;/p&gt;
&lt;h3 id=&#34;more-engineering-management-posts&#34;&gt;More Engineering Management Posts&lt;/h3&gt;
&lt;p&gt;This is part of a series of posts on Engineering Management.  You can see the whole series &lt;a href=&#34;https://benmccormick.org/engineering-management-thoughts&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Engineering Management: Choosing What To Work On</title>
      <link>https://benmccormick.org/2021/02/20/190000.html</link>
      <pubDate>Sat, 20 Feb 2021 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2021/02/21/190000.html</guid>
      <description>&lt;p&gt;&lt;em&gt;I&amp;rsquo;m currently taking some time away from my job on parental leave, and it seemed like a good time to reflect on the lessons I&amp;rsquo;ve learned the last few years about engineering management, this is my second post here, a followup to my post on &lt;a href=&#34;https://benmccormick.org/2021/02/18/what-do-ems-do&#34;&gt;What EMs do&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;In my last post I listed a &lt;a href=&#34;https://benmccormick.org/2021/02/18/what-do-ems-do&#34;&gt;bunch of different things&lt;/a&gt; that engineering managers can do to produce value.  Given the sheer number of things that engineering managers can consider doing to help their teams and make an impact, the next question quickly becomes: how do I balance my time and work on the right things?  I think of this in terms of maintaining rhythms, finding high leverage work, and following some principles for maintaining sanity.&lt;/p&gt;
&lt;p&gt;There are a number of &lt;strong&gt;rhythms&lt;/strong&gt; that I try to maintain every week.  For me these include 1-1s with my team, our agile sprint rituals, preparing weekly updates for our VPE and CTO, and dedicated time set aside for strategic work.  I focus on protecting these times and as much as possible, but also maintain a pretty high bar for what type of thing I set up as a recurring meeting or obligation.  I draw a distinction here between things I do a lot, and things I try to do &lt;em&gt;every&lt;/em&gt; day/week/sprint/month.  Making it a regular commitment prevents these things from being washed away by busy periods and unlocks the compounding benefits of something that is routinely practicied.&lt;/p&gt;
&lt;p&gt;Rhythms are a great fit for activities that are high value but low urgency, like maintaining important relationships, keeping up good information flow, and protecting time for longer term creative work.  The important thing here is being selective and as I&amp;rsquo;ll discuss more below, making sure to review regularly to make sure they&amp;rsquo;re still a good use of time.  Rhythms become an anti-pattern when they get disconnected from value &amp;ndash; when you keep doing something that is no longer providing value &amp;ndash; a zombie standup meeting or a regular meeting with another team that could just be handled through async communication.  I doubt that there is a universal ideal ratio of rhythms to unstructered time, but for me personally I end up having about 20 hours each week that is preblocked for the same activities every week, and that has felt like an appropriate tradeoff between the urgent and new with the consistent and important.&lt;/p&gt;
&lt;p&gt;With my remaining time I try to focus as much as possible on &lt;strong&gt;high leverage activity&lt;/strong&gt;.  As in my last post I&amp;rsquo;m borrowing language from Andy Grove&amp;rsquo;s &lt;a href=&#34;https://amzn.to/2ZvSXnP&#34;&gt;High Output Management&lt;/a&gt; here &amp;ndash; leverage is simply a term for an activity&amp;rsquo;s value relative to its cost in time/effort.  So training somebody to do repeating work is often higher leverage than doing it yourself; you pay a one time cost to get an ongoing benefit of the task being completed and growing one of your teammate&amp;rsquo;s careers.  If the term leverage doesn&amp;rsquo;t speak to you, you can think of the pareto principle and trying to work on the 20% of stuff that brings 80% of the value, or working &amp;ldquo;smarter not harder&amp;rdquo;.  The point is to figure out what activities are going to have outsized impact and push to prioritize them.&lt;/p&gt;
&lt;p&gt;Will Larson has a good guide on identifying &lt;a href=&#34;https://staffeng.com/guides/work-on-what-matters&#34;&gt;work that matters&lt;/a&gt;.  It&amp;rsquo;s focused on staff-plus engineers, but the principles apply to EMs equally well.  Once you&amp;rsquo;ve exhausted low effort high value efforts, there&amp;rsquo;s more value in taking on the bigger problems that will truly impact a company.  Swarm on existential issues, but otherwise try to find places to work where there&amp;rsquo;s room to make impact but you will get support.  You can scale your impact by investing in people and &lt;em&gt;nudging&lt;/em&gt; or editing other folks approaches without having to own everything yourself or by helping them finish projects that need a bit of help getting to done.  And it&amp;rsquo;s important to see if there are only things that you can do.  I can&amp;rsquo;t phrase this better than Will did so I would highly recommend reading the whole thing on his site. I would add that for managers ultimately all of our value will disappear if we do not have a high-performing team that is able to stick together and make progress over time.  I&amp;rsquo;ve never regretted spending time investing useful time into my team.&lt;/p&gt;
&lt;p&gt;Of course in real life, picking high leverage activities is not an exercise where we calmly sit back and pick from a neatly arranged menu of options.  Instead as an EM you will be bombarded with requests for your time; meetings with other teams and departments, project meetings, compliance documentation, onboarding new employees, performance reviews, mandatory company trainings, process improvement discussions, status update requests and more.  Some of these things will be high value and important, depending on the culture of your company almost all of them may appear urgent.  It isn&amp;rsquo;t a productive goal to only ever work on the most important things at all time.  There will always be urgent work that you&amp;rsquo;ll find you feel you need to do.  However there are better and worse ways to handle this flood of urgency.&lt;/p&gt;
&lt;p&gt;Effective managers know the importance of saying &lt;em&gt;no&lt;/em&gt; to many things in order to focus on the essential.  There&amp;rsquo;s space to grow beyond that though &amp;ndash; a &lt;em&gt;no&lt;/em&gt; that preserves a manager&amp;rsquo;s integrity is better than a &lt;em&gt;yes&lt;/em&gt; that they fail to follow through on, or one that leads to them working on the wrong things.  But even better is if they can work with the people making requests on their time to find ways to make the urgent request smaller, or help get it delegated to people who will grow through the work.  Ultimately managers are as effective as their relationships and finding ways to say yes without getting distracted from the most important work is a valuable advanced skill.  Of course the temptation can be to trade away these hard decisions and problems by simply giving more time.&lt;/p&gt;
&lt;p&gt;Working more hours is the ultimate short term time management power move.  It&amp;rsquo;s also a quick path to &lt;a href=&#34;https://benmccormick.org/2020/08/31/simple-burnout-triage&#34;&gt;burnout&lt;/a&gt;.  I try to follow a few &lt;strong&gt;principles&lt;/strong&gt; to keep my schedule sane.&lt;/p&gt;
&lt;p&gt;First it&amp;rsquo;s important to reconsider your time commitments regularly, especially any recurring meetings/commitments.  Many recurring meetings degrade in usefulness over time, and even ones that should be a bedrock of a manager&amp;rsquo;s schedule like 1-1s may need to be adjusted as the needs of the participants change.  I try to reconsider my calendar as a whole at least once a quarter, and anytime I have what feels like an unproductive meeting or a scattered day I try to think through whether I can make any adjustments to my schedule to improve in the future.   This can be as simple as Lara Hogan&amp;rsquo;s concept of &lt;a href=&#34;https://larahogan.me/blog/manager-energy-drain/#calendar-color-coding-and-defragging&#34;&gt;defragging my calendar&lt;/a&gt; to put similar things together and clear creative space, or involve reworking a meeting that has gone stale to be more useful for the team &amp;ndash; maybe even reducing its frequency or canceling it and replacing it with an async process.&lt;/p&gt;
&lt;p&gt;My second principle is that constraints are good.  Any EM will have an essentially infinite amount of work.  There&amp;rsquo;s always more training, strategy, preparation and planning that can be done.  If you&amp;rsquo;re still comfortable coding that represents another near-infinite pool of potential contribution.  A &lt;em&gt;work till it&amp;rsquo;s all done&lt;/em&gt; approach simply won&amp;rsquo;t succeed.  There is always more.  So I try to embrace a schedule and accept that schedule as a constraint to solve for in my work.  At points this has been a literal daily stopping time for me &amp;ndash; more commonly in my career I&amp;rsquo;ve simply held a value of being there for my family and protecting family time, as well as protecting my health and time to take care of it.  That has meant that at times I have flexibility to pour a lot of time into work, and other times I&amp;rsquo;m more limited in my total time to devote to work.  In each case though I&amp;rsquo;m able to take a finite amount of time and do my best to optimize it for the challenges in front of me.&lt;/p&gt;
&lt;h3 id=&#34;stay-sane-keep-your-integrity-and-remember-that-people-matter-the-most&#34;&gt;Stay Sane, Keep Your Integrity, and Remember That People Matter The Most&lt;/h3&gt;
&lt;p&gt;Managing your time in more senior roles is hard.  You&amp;rsquo;re not given the direction that you may have gotten used to as an IC engineer, and a lot of the most important work won&amp;rsquo;t have a timer or anyone yelling at you to get it done.  If you&amp;rsquo;re struggling with this I recommend giving yourself grace.  And if you take anything from this piece I hope you remember to protect yourself with constraints so that you stay sane, avoid compromising your integrity by over-committing and ultimately err on the side of investing in people.  In 5 years it will be the people you&amp;rsquo;re interacting with today who are going to have the biggest impact on your career, and as I look at the scope of the rest of my life I expect it to be my impact on people that I remember for better or worse, much more than the results of a project or whether I nailed a certain process for my team.&lt;/p&gt;
&lt;h3 id=&#34;more-engineering-management-posts&#34;&gt;More Engineering Management Posts&lt;/h3&gt;
&lt;p&gt;This is part of a series of posts on Engineering Management.  You can see the whole series &lt;a href=&#34;https://benmccormick.org/engineering-management-thoughts&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Engineering Management: What do EMs do anyway?</title>
      <link>https://benmccormick.org/2021/02/17/190000.html</link>
      <pubDate>Wed, 17 Feb 2021 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2021/02/18/190000.html</guid>
      <description>&lt;p&gt;&lt;em&gt;I&amp;rsquo;m currently taking some time away from my job on parental leave, and it seemed like a good time to reflect on the lessons I&amp;rsquo;ve learned the last few years about engineering management, starting with a base assumption of what it is that engineering managers actually do&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;There are a lot of different ideas out there about what engineering managers actually do, from pithy one liners like &amp;ldquo;nothing&amp;rdquo; or &amp;ldquo;meetings&amp;rdquo; to detailed expectations that sound like a superset of tech lead, project manager, and people manager roles.  When I got started in management I quickly found that at fast growing companies people will happily flow as much work as possible to EMs, and it&amp;rsquo;s important to have a clear idea of what your job really is, because the workload will quickly become larger than one person can do &amp;ndash; at which point effective managers excel primarily because of good time management and prioritization.  Those skills start by understanding your core responsibilities.&lt;/p&gt;
&lt;p&gt;In &lt;a href=&#34;https://amzn.to/2ZvSXnP&#34;&gt;High Output Management&lt;/a&gt; Andy Grove summarizes a manager&amp;rsquo;s output as the sum of the output of his team and the output of neighboring teams that he influences.  A manager&amp;rsquo;s goal then is to maximize those outputs &amp;ndash; a framing that is helpful to come back to when it comes to prioritizing work.  Making good choices of what to work on is a &lt;a href=&#34;https://benmccormick.org/2021/02/21/ems-choosing-what-to-work-on&#34;&gt;different article&lt;/a&gt;, but for now I&amp;rsquo;d like to consider a semi-comprehensive list of the different areas a manager can focus to influence those outputs. In my career and reading I&amp;rsquo;ve seen a pretty consistent set of 3 high level areas that effective managers invest in: facilitating information flow, driving progress forward, and building a sustainably productive team.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Facilitating information flow&lt;/strong&gt; includes a mix of information gathering and information sharing.  Engineering Managers are responsible for doing the work to understand what is happening in their team and also understand what is happening in the broader organization.  Effective EMs then find useful ways to synthesize and share that information to help their teams be more effective and give other teams and executives clarity into what is happening with their team.  There are a multitude of anti-patterns here including undersharing or oversharing in either direction, manipulating people via information flow, and failing to extract and emphasize the most critical pieces of information.  But doing this right means bringing clarity to everyone an EM works with, pushing the most important information to the people who need it and making it easy for people to pull other information when needed.&lt;/p&gt;
&lt;p&gt;Tools for facilitating information flow include 1 on 1 meetings, building or advocating for processes and tools that expose team and project status clearly, encapsulating decisions and reasoning in documents that can be shared widely and referenced later, and asking good questions in standups and project meetings that lead to better understanding of problems and any misalignments between the team and the business.  Getting good at this stuff means being a good written and verbal communicator, keeping an attitude of curiousity and humility that lets you learn from others and stay up to date with what is going on, and being intentional about building relationships with all of the key people you work with.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Driving progress forward&lt;/strong&gt; breaks down into 3 parts: decision influencing, delegating/monitoring and &amp;ldquo;doing the work&amp;rdquo;.  The first item here is phrased as &lt;em&gt;decision influencing&lt;/em&gt; rather than decision making because while you will have to make many decisions as an Engineering Manager it is even more common and in many cases more desirable that you&amp;rsquo;ll be providing input and influence on decisions but not ultimately &amp;ldquo;owning&amp;rdquo; the decision yourself.  &lt;a href=&#34;https://benmccormick.org/2021/02/26/ems-how-to-delegate&#34;&gt;Delegating work to others&lt;/a&gt; is an important part of getting things done and scaling yourself as a manager, but to again quote Andy Grove &amp;ldquo;delegation without follow-through is abdication&amp;rdquo;.  So even delegated tasks still require the work of monitoring and supporting, and thus take time.  Finally, EMs sometimes take on work that is actually directly part of their teams day to day &amp;ndash; writing code for a feature, designing architecture for an upcoming project, or debugging a production issue.  That last point is the most controversial &amp;ndash; there are plenty of &amp;ldquo;engineering managers shouldn&amp;rsquo;t code&amp;rdquo; zealots out there.  I simply add it here as something an EM &lt;em&gt;can&lt;/em&gt; do to increase their team&amp;rsquo;s output.  Whether it is an effective or impactful activity is going to be highly context specific and is out of the scope of this article.&lt;/p&gt;
&lt;p&gt;Progress on a team&amp;rsquo;s work has the shortest feedback loop of the 3 top level areas: missing information can often go unnoticed for a while, and unhappy teams&#39; troubles may take a while to manifest.  But everybody notices when your team is not succeeding at it&amp;rsquo;s goals.  Thus the anti-patterns here are often trading off team and communication for an appearance of progress: doing too much work yourself at the expense of your team&amp;rsquo;s development and long term scalability, failing to take responsibility for your team&amp;rsquo;s output &amp;ndash; often by delegating without supporting a teammate, or making decisions that optimize for making yourself look good at the expense of your team or other parts of your organization.  Getting really good at driving progress as an engineering manager means learning to delegate with an appropriate amount of support and monitoring, learning how to influence work usefully without having to own it end to end and being strategic about what you yourself try to own.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Building a sustainably productive team&lt;/strong&gt; involves a mix of hiring, culture shaping, team development, and what &lt;a href=&#34;https://twitter.com/rands&#34;&gt;Michael Lopp&lt;/a&gt; calls the &lt;a href=&#34;https://randsinrepose.com/archives/bored-people-quit/#:~:text=care%20and%20feeding%20of%20engineers&#34;&gt;care and feeding of engineers&lt;/a&gt;.  Hiring new engineers is arguably the highest leverage activity we undertake as engineering managers &amp;ndash; it&amp;rsquo;s a one time process that will have impacts on your team for years.  Engineering managers have outsized influence on their team&amp;rsquo;s culture: what work is valued, what the expectations are for meeting preparation and timeliness, how people are treated, what type of people and ideas are welcome.  This is often influenced as much by what EMs neglect as what they do.  EMs can help their teammates develop through &lt;a href=&#34;https://benmccormick.org/2021/03/07/ems-how-to-give-feedback&#34;&gt;thoughtful feedback&lt;/a&gt;, coaching, sponsorship and training.  And we work in an industry where our teammates usually have many great work options &amp;ndash; setting aside the moral case for being a compassionate manager, managers that do not care for their employees, understand their needs, concerns and ambitions, and help them thrive are unlikely to develop a sustainably productive team over any length of time.&lt;/p&gt;
&lt;p&gt;The biggest anti-pattern here is simply neglecting the work &amp;ndash; I&amp;rsquo;ve worked for and around managers who simply didn&amp;rsquo;t take the time to regularly talk with their team, were not mindful of the impact their actions had on culture, or treated their employees as replacable cogs in an industrial machine.  Even hiring is often not given the investment it deserves based on impact: many managers are content to offload sourcing and evaluation to other people or put minimal time into preparing for interviews and new job postings.  Getting really good at building a sustainable team means thinking of yourself as a role model for the behavior you want to see, investing heavily in hiring and supporting your current team, regularly giving and seeking meaningful feedback and being organized about helping your team in their career growth.&lt;/p&gt;
&lt;h3 id=&#34;its-all-about-outcomes&#34;&gt;It&amp;rsquo;s all about outcomes&lt;/h3&gt;
&lt;p&gt;I labeled this list as semi-comprehensive because while most of the valuable work I do as an engineering manager falls under one of the categories above, managing engineers is fundamentally different than the type of work someone who has just been promoted from a mid-senior engineering role might be used to.  Instead of taking tasks or projects to completion, you&amp;rsquo;re now operating at a level of an organization where the expected deliverables get a little hazier and you&amp;rsquo;re being asked to achieve higher level business outcomes.&lt;/p&gt;
&lt;p&gt;So don&amp;rsquo;t be afraid to shift the time you spend on different parts of this list over time or even do work that seems a bit far afield from your role.  If it&amp;rsquo;s grounded in a desire to produce good outcomes for the business and help your team and it won&amp;rsquo;t get done without you stepping in, consider it part of the job.&lt;/p&gt;
&lt;h3 id=&#34;more-engineering-management-posts&#34;&gt;More Engineering Management Posts&lt;/h3&gt;
&lt;p&gt;This is part of a series of posts on Engineering Management.  You can see the whole series &lt;a href=&#34;https://benmccormick.org/engineering-management-thoughts&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Driving Change Without Authority</title>
      <link>https://benmccormick.org/2021/01/18/190000.html</link>
      <pubDate>Mon, 18 Jan 2021 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2021/01/19/190000.html</guid>
      <description>&lt;p&gt;I recently had a conversation with a coworker where they mentioned that they didn&amp;rsquo;t feel like they had the same power to change other people&amp;rsquo;s behavior that I did since I was a manager.  It&amp;rsquo;s a common sentiment that has some truth but usually will make a manager start laughing or crying if you suggest that it represents reality.  Managing people well involves very little imposing your will on a situation and a lot more driving change indirectly.  The good news is that most of the techniques for this type of indirect change not only can be used by non-managers, many of them are actually more effective coming from engineers directly.  A lot of these techniques deserve posts of their own and I intend to keep these short, so consider this a brainstorming list for the next time you want to change something on your team and don&amp;rsquo;t feel empowered to do so.&lt;/p&gt;
&lt;h3 id=&#34;build-the-thing-you-want-to-exist&#34;&gt;Build the thing you want to exist&lt;/h3&gt;
&lt;p&gt;A software engineer&amp;rsquo;s ultimate power move is the ability to create new things.  If you&amp;rsquo;re in an argument on the best path forward for a project, just going ahead and building the thing you think should exist can be incredibly powerful.  This could be a proof of concept for larger things, or the full thing for smaller features.  Opposition and bikeshedding often melts away in the face of a working example of the future.  This is especially effective if the argument has been about whether your preferred solution is possible.&lt;/p&gt;
&lt;p&gt;Note that this path can be overused, is helped along by a gentle touch, and I wouldn&amp;rsquo;t recommend it if you put so much time and effort into it that you&amp;rsquo;d be crushed if people still said no.  But it is a powerful way to move discussions forward.&lt;/p&gt;
&lt;h3 id=&#34;make-it-easier&#34;&gt;Make it easier&lt;/h3&gt;
&lt;p&gt;Do you want everybody to write more/better tests?  Create some best practice examples and documentation.  Maybe make some training videos showing how you write tests.  Write some helpers to encompass common testing patterns.  Make sure your testing tools are updated to versions with the latest features, and consider whether there are different tools you can use to make adoption easier.  This type of work is also great for establishing yourself as an expert in the area (see below).&lt;/p&gt;
&lt;h3 id=&#34;make-your-preference-a-default&#34;&gt;Make your preference a default&lt;/h3&gt;
&lt;p&gt;Similar to making it easier, you can often change behavior simply by making it the path of least resistance.  Want people to use spaces instead of tabs?  Encode that into a linter and set it to run against every Pull Request.  Want to make sure people add information to new issues?  Create an issue template.  Humans are very susceptible to &lt;a href=&#34;https://amzn.to/3930gJz&#34;&gt;nudges&lt;/a&gt; and default behaviors, and are much more willing to accept new behaviors when they don&amp;rsquo;t require conscious action from them.&lt;/p&gt;
&lt;h3 id=&#34;identify-allies-and-opponents&#34;&gt;Identify allies and opponents&lt;/h3&gt;
&lt;p&gt;If you want to change behavior in your team, it can be helpful to have multiple people fighting for a change.  A great place to start here is just identifying who agrees with you.  Not everyone who is willing to accept a change might want to fight for it as much as you, but establishing an understanding of where people stand is helpful for you to identify potential allies as well as people who you may have to work harder to convince.&lt;/p&gt;
&lt;p&gt;When you know who &lt;em&gt;disagrees&lt;/em&gt; with you, those people can actually be the most helpful in helping you move a change forward if they&amp;rsquo;re willing to give clear feedback, since they&amp;rsquo;ll help establish the conditions under which a team might accept a change.&lt;/p&gt;
&lt;p&gt;If you find that you&amp;rsquo;re primarily fighting apathy rather than opposition, it can be a good time to pivot to other methods like &amp;ldquo;making it a default&amp;rdquo; or &amp;ldquo;show the future&amp;rdquo;.&lt;/p&gt;
&lt;h3 id=&#34;show-the-future&#34;&gt;Show the future&lt;/h3&gt;
&lt;p&gt;In his 1936 classic &lt;a href=&#34;https://amzn.to/3oZu7Yx&#34;&gt;How To Win Friends and Influence People&lt;/a&gt;, Dale Carnegie said that one of the fundamental techniques in working with people was &amp;ldquo;Arouse in the other person an eager want&amp;rdquo;.  When we want to drive forward a change and are faced with apathy, often times the issue is that other people don&amp;rsquo;t understand why the change we&amp;rsquo;re advocating would be valuable for them.&lt;/p&gt;
&lt;p&gt;A great technique in this case is to be crystal clear on what we expect to get from the change &amp;ndash; and to do so in a way that resonates with them.  If we want to have more automated tests, we might explain to our fellow engineers that more tests can help prevent future rolled back releases, resulting in less crunch time work.  Meanwhile, our product manager might be more interested to know that it will result in fewer angry customers and missed deadlines due to rework.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s important not to oversell here.  If you make it sound like adding a few tests will remove all quality issues with your product this route can backfire with the team quickly dropping support when the initial results underwhelm.  But understanding and explaining the &amp;ldquo;why&amp;rdquo; in a way that resonates with every relevant teammate is a powerful technique.&lt;/p&gt;
&lt;h3 id=&#34;ask-authentic-questions&#34;&gt;Ask authentic questions&lt;/h3&gt;
&lt;p&gt;When you are looking to change things and it feels like you&amp;rsquo;re the only one who sees the value in what you&amp;rsquo;re doing a great place to start can be asking authentic questions of others.  For instance, if we went back to our testing example you might ask &amp;ldquo;Do you think writing more tests would be valuable?&amp;rdquo;, &amp;ldquo;why do you think we don&amp;rsquo;t write more tests now&amp;rdquo;, or &amp;ldquo;how do you think our test suite should evolve from here?&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;If asked sincerely those questions will help you refine your understanding of the challenge in front of you, will open the minds of the people you&amp;rsquo;re asking toward the challenge, and may win some converts just by including people.  The sincerely part is important here though - people can generally tell when you&amp;rsquo;re actually listening to what they have to say versus including perfunctory &amp;ldquo;feedback requests&amp;rdquo; on your way to pushing an agenda.&lt;/p&gt;
&lt;h3 id=&#34;work-in-public&#34;&gt;Work in &amp;ldquo;public&amp;rdquo;&lt;/h3&gt;
&lt;p&gt;When you&amp;rsquo;re trying to encourage a particular practice it can be helpful to demonstrate the work &amp;ldquo;in public&amp;rdquo;.  So if you want people writing more tests, share screenshares of yourself writing tests, run a brown bag lunch where you do some live coding, or share your test PRs in a public slack channel where people will see it.  You might even write public blog posts about the work you&amp;rsquo;re doing, or speak about it at a meetup.&lt;/p&gt;
&lt;p&gt;There are a few goals here: to show people what it looks like to do the work, to &amp;ldquo;normalize&amp;rdquo; the practice, and to give it visibility.  Doing work publically like this can be a way to attract other interested folks who you might not have expected to be sympathetic, it can raise your own profile, and it can be a way to get great feedback.&lt;/p&gt;
&lt;h3 id=&#34;explain-your-work&#34;&gt;Explain your work&lt;/h3&gt;
&lt;p&gt;One mistake I see people who are trying to drive change make is an assumption that everybody understands what they&amp;rsquo;re doing.  When you&amp;rsquo;re first introducing a new technology, process, or improvement to your team you should always assume that you need to make the case for it, starting with clearly explaining what the change is and what you&amp;rsquo;re intending to accomplish with it.&lt;/p&gt;
&lt;p&gt;This technique can be combined with many of the other ones here, and can be accomplished in many ways.  A short RFC style document where you outline the change you want can be great.  Putting extra detailed comments and descriptions into pull requests where you&amp;rsquo;re implementing a desired change can be helpful, as can screencasts, blog posts, or brown bags.  For smaller changes this may just mean going out of your way to be extra explicit about the &amp;ldquo;why&amp;rdquo; when you make pull request comments requesting people to move in a certain direction.&lt;/p&gt;
&lt;h3 id=&#34;establish-your-expertise&#34;&gt;Establish your expertise&lt;/h3&gt;
&lt;p&gt;As I said at the beginning, &amp;ldquo;change by authority&amp;rdquo; is not generally the best path.  People are happier doing things because they see the value, not because somebody told them to do so.  That said, sometimes change does need to come through authority.  When that is the case though, there are two types of relevant authority in most engineering organizations.  Hierarchical authority (IE directives from somebody with a managerial title above you in a reporting relationship) and expertise authority.  While hierarchical authority changes slowly and comes with all sorts of other pros and cons, anyone can develop the authority of expertise with a level of dedication and work.&lt;/p&gt;
&lt;p&gt;If you want to drive testing culture on your team it can be helpful to establish yourself as an expert on testing.  The bar for this might be quite high or quite low depending on your existing culture, but the path is similar either way; do the work consistently over time, educate yourself, and demonstrate the impact of the work you&amp;rsquo;re doing.  A little bit of this might not go very far, and if the organization explicitly doesn&amp;rsquo;t value the change you&amp;rsquo;re trying to make it is possible that expertise won&amp;rsquo;t change the equation here.  But if there is willingness to consider growth, establishing yourself as an expert will ensure that you will be part of the conversations when it is time to make a change, and you&amp;rsquo;ll get to contribute to making change happen.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Play Other Positions!</title>
      <link>https://benmccormick.org/2020/12/31/190000.html</link>
      <pubDate>Thu, 31 Dec 2020 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2021/01/01/190000.html</guid>
      <description>&lt;p&gt;This fall &lt;a href=&#34;https://www.espn.com/nfl/story/_/id/29853800/i-was-wide-open-how-ben-roethlisberger-season-receiver-helped-qb&#34;&gt;ESPN published an article&lt;/a&gt; about Steelers QB Ben Roethlisberger&amp;rsquo;s high school stint as a Wide Receiver and how it benefited him as he moved forward in his career.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Before he set records as a quarterback his senior year, before he became the Pittsburgh Steelers&#39; top draft pick out of Miami (Ohio), and before he won two Super Bowl rings as one of the NFL&amp;rsquo;s best signal-callers, Roethlisberger spent his junior year of high school playing wide receiver.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;It gave Roethlisberger a deeper understanding of the game he took with him the rest of his career &amp;ndash; something he found again last season as he stood on the sideline following a season-ending elbow injury in Week 2.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;[Findlay] coach [Cliff Hite] was always like, &amp;lsquo;It benefited you as a senior playing quarterback from playing wide receiver your junior year,&#39;&amp;rdquo; Roethlisberger said. &amp;ldquo;I never understood it at the time, but I think it does to a certain extent because you can see the other side of it.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The article highlights 2 advantages of the previous receiver experience for Roethlisberger.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Roethlisberger&amp;rsquo;s stint as a receiver enables him to be clear with his instructions. Nothing gets lost in translation when the quarterback can give his directives in a way the receiver clearly understands.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;He can talk our language,&amp;rdquo; said Ryan Switzer, who played with Roethlisberger in Pittsburgh for two seasons. &amp;ldquo;He can talk leverage, he can talk technique, he can talk lean and press, he can talk all these things, which makes the communication a lot more fluid between us and him. &amp;hellip; He&amp;rsquo;s able to communicate really well, which helps translate to being on the same page more often on the field.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;The carryover from one position to another goes beyond communication. Iriti sees it in the way Roethlisberger eludes the pass rush and finds a receiver on a broken play.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;It&amp;rsquo;s like he knows where he&amp;rsquo;s at, and he knows where you&amp;rsquo;re trying to go, so he can wait until that last second, just make that little move,&amp;rdquo; Iriti said. &amp;ldquo;It&amp;rsquo;s not fast, it&amp;rsquo;s not quick, but it&amp;rsquo;s like it&amp;rsquo;s premeditated that he knows where you&amp;rsquo;re going. So it makes him seem more agile and quick than he actually is. He&amp;rsquo;s not a blazing-fast guy, but instinctively he&amp;rsquo;s really smart.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Playing a position that he later had to collaborate with allowed Roethlisberger to communicate with his teammates better and make better adjustments when things went wrong and he needed to understand or anticipate his teammates reactions.&lt;/p&gt;
&lt;p&gt;Reading Roethlisberger&amp;rsquo;s stories reminded me of some of my own practices as a high school basketball player. Our coaches would force us to switch positions around when practicing plays.  The theory was that you didn&amp;rsquo;t really know a play until you could execute on every position&amp;rsquo;s part of it.  As a tall but gawky and uncoordinated high schooler, I was never likely to move away from my forward position to become a full time point guard, but the exercise was useful both for the reasons called out above, as well as the flexibility it gave us to play different lineups for shorter stretches during a game.  If we had problems with injuries or foul trouble, we could get away with playing people at a different position for some stretch of time, or play different groupings of players that let us take advantage of matchups.&lt;/p&gt;
&lt;p&gt;So what does any of this have to do with the purported topic of this blog, productive software teams?  It turns out that modern software teams have a lot in common with sports teams.  They&amp;rsquo;re a collection of individuals with different skillsets who take on different roles to work together towards a set of goals over time.  Our work has less black and white scorekeeping, and the lines between &amp;ldquo;games&amp;rdquo; are a lot blurrier, but there is a lot we can learn from the world of sports.&lt;/p&gt;
&lt;p&gt;The lessons from my high school basketball days have stuck with me as I&amp;rsquo;ve progressed through my software career.  I find that I collaborate better with my teammates when I have some sense of what it is like to do their job.  A benefit of spending the last 7 years in startups was the opportunity to wear a lot of different hats on a short term basis.  I&amp;rsquo;ve always done an mix of front end and backend development. I once was assigned the role of being primary test engineer for a major release while our normal QA lead was taking a few weeks off out of the country.  As my career advanced I got to get more involved with the product management side of things, collaborating closely with PMs to help shape how products got built.  I even spent a memorable and painful couple months as my team&amp;rsquo;s primary designer after a round of layoffs.  As both an individual contributor and an engineering manager, these experiences have helped me work well with a variety of different people, identify times when teammates in different roles were talking past each other, and plug gaps when the need arose. It also gives me empathy for people who are facing the tough parts of their job, and a level of humility when approaching discussions that comes from knowing there are always many perspectives on a particular problem or process.&lt;/p&gt;
&lt;p&gt;Unlike sports, we don&amp;rsquo;t usually consciously &amp;ldquo;practice&amp;rdquo; in software development.  That may be a mistake, but given it is the world we live in, how do we actually develop this type of experience?  I&amp;rsquo;ve found 3 primary things helpful: doing the work, talking with people experienced in the role, and reading about the role.  This isn&amp;rsquo;t that different than the learning process if you actually wanted to pursue a particular role, the time commitment is just lower.&lt;/p&gt;
&lt;p&gt;If you have the ability to just do a piece of a project in a different role or fill in for someone for a short time, that can be the easiest way to quickly develop some intuition about a role.  For some role combos that&amp;rsquo;s pretty easy.  A software engineer can always take a shot at doing more of a test engineer role.  Look at another developer&amp;rsquo;s code and think about how you would test it. You probably won&amp;rsquo;t be doing what a full time test engineer would do, but just getting into the mindset can be helpful.  It can feel harder to cover other roles - how would you &amp;ldquo;try out&amp;rdquo; being an engineering manager as a junior engineer?  But you might be able to ask the person in that role if there&amp;rsquo;s some part of their job you can help them with.  Then you get to try out a piece of the role and potentially get some guidance to go with it.&lt;/p&gt;
&lt;p&gt;One problem with &amp;ldquo;just doing it&amp;rdquo; is that when we first try a new skill or role, we don&amp;rsquo;t know what we don&amp;rsquo;t know.  It&amp;rsquo;s easy to perform a parody of the role if we don&amp;rsquo;t get any meaningful feedback on our performance.  So it is helpful to talk with somebody who is experienced in the role, ideally an expert.  They can give you feedback on your attempts or just tell you about what they do and how they see the world.  The ability to listen well and ask good questions can take you far here.&lt;/p&gt;
&lt;p&gt;Finally, there are a lot of written resources out there for learning about different roles.  To help work with people in a certain role it can help to read some of the &amp;ldquo;classic&amp;rdquo; essays or books about a role.  A learning-focused person in the role will be able to make recommendations, but if you don&amp;rsquo;t have a good resource there you can get a similar effect with careful googling for &amp;ldquo;best books for product managers&amp;rdquo; or similar.  Some books I&amp;rsquo;ve found helpful for understanding different roles include &lt;a href=&#34;https://amzn.to/2KVewdZ&#34;&gt;Inspired&lt;/a&gt; for product managers, &lt;a href=&#34;https://amzn.to/3hx6Iee&#34;&gt;The Manager&amp;rsquo;s Path&lt;/a&gt; for engineering managers, and &lt;a href=&#34;https://amzn.to/3hyC6ca&#34;&gt;The Design of Everyday Things&lt;/a&gt; for product designers.&lt;/p&gt;
&lt;p&gt;For pretty much every piece of career advice out there, there are pathological variations that should be avoided.  Almost everything can be taken too far or stripped of context to the point where it becomes harmful.  I&amp;rsquo;ve seen at least one common way that the pursuit of understanding our teammates roles can go wrong.  That is simple ego; it can be tempting to believe that because we&amp;rsquo;ve walked a mile in somebody&amp;rsquo;s shoes we&amp;rsquo;re the experts and our voices should now hold heavy weight when making decisions in our teammates area of expertise.  We should always be listening to our teammates and taking in different opinions. However, it is still valuable to have &amp;ldquo;owners&amp;rdquo; for a role, and spending a week or a month or even a year working in a role is not the same as making it your career.  There are going to be times where a more experienced team will need to support somebody in their role, especially if they&amp;rsquo;re new.  But that&amp;rsquo;s not the same as you &amp;ldquo;being able to do it better&amp;rdquo; or &amp;ldquo;having veto power&amp;rdquo;.  This can get quite bad; I&amp;rsquo;ve known engineers who genuinely believed that they could step in and do any role in their company better than the people who had made it their careers.  This is the opposite of the empathy we&amp;rsquo;re trying to create.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m wary about aggrandizing this advice.  Trying other roles is a simple technique for working better with your teammates and it isn&amp;rsquo;t going to change the world.  But I&amp;rsquo;m writing this on the first day of 2021.  2020 was a year that was marked by a lot of suffering and struggle across our world, and also one that seemed to me to lead many people away from empathy and connection and toward conflict.  Consider this as a simple way to build empathy and connection with your teammates this year.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>2020 Roundup</title>
      <link>https://benmccormick.org/2020/12/29/190000.html</link>
      <pubDate>Tue, 29 Dec 2020 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2020/12/30/190000.html</guid>
      <description>&lt;p&gt;2020 was the 7th full year of this blog, and it was by far the quietest in terms of output.  For reasons that are both obvious (global pandemic!) and personal (toddler, puppy, still learning a new job) writing has been on the backburner for a year.  I hope to change that in 2021, but with another child on the way in February I&amp;rsquo;m not foolish enough to make any promises here.&lt;/p&gt;
&lt;p&gt;I only published 5 posts this year, with the posts generally focused on what I was reading and learning as an engineering manager.&lt;/p&gt;
&lt;h3 id=&#34;most-read-post-published-in-2020&#34;&gt;Most Read Post Published in 2020&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://benmccormick.org/2020/08/31/simple-burnout-triage&#34;&gt;Simple Burnout Triage&lt;/a&gt; - This post got picked up by &lt;a href=&#34;https://changelog.com/&#34;&gt;The Changelog&lt;/a&gt; which led to a pretty large spike &amp;ndash; but it also is obviously a topic that a lot of people are working through in 2020.  Given that this got 70x more views than any of my other new posts this year, it can hog the summary spotlight all by itself this year.&lt;/p&gt;
&lt;h3 id=&#34;languages-and-libraries-i-used-a-lot-of-in-2020&#34;&gt;Languages and Libraries I used a lot of in 2020&lt;/h3&gt;
&lt;p&gt;JavaScript (ES6 + TypeScript), React, Node + Express, lodash, Jest, Redux&lt;/p&gt;
&lt;p&gt;But realistically this was my first year spending significantly more time focused on people &amp;amp; product management than hands on software work&lt;/p&gt;
&lt;h3 id=&#34;tech-i-want-to-try-in-2021&#34;&gt;Tech I want to try in 2021&lt;/h3&gt;
&lt;p&gt;My code time is limited these days &amp;ndash; but I&amp;rsquo;d like to go deeper into some of the cool new stuff around React like Server Components, and also learn Terraform.&lt;/p&gt;
&lt;h3 id=&#34;blogs-i-started-following-in-2020&#34;&gt;Blogs I started following in 2020&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://cutlefish.substack.com/&#34;&gt;The Beautiful Mess by John Cutler&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;blogs-i-read-every-post-from-in-2020&#34;&gt;Blogs I read every post from in 2020&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://lethain.com/&#34;&gt;Irrational Exuberance! by Will Larson&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://larahogan.me/&#34;&gt;Lara Hogan&amp;rsquo;s Engineering Leadership blog and newsletter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://randsinrepose.com/&#34;&gt;Rands In Repose&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;software-i-used-nearly-every-day-in-2020&#34;&gt;Software I used (nearly) every day in 2020&lt;/h3&gt;
&lt;p&gt;MacOS/iOS, Google Search, Chrome, GMail/MailPlane 3, Twitter/Tweetbot, Feedbin/Reeder, iMessage, Slack, Jira, 1Password, VS Code, iTerm, Fish Shell, Github, Fantastical, Spotify, Bear -&amp;gt; Roam Research, CloudApp, Dash, Postman, Complice&lt;/p&gt;
&lt;h3 id=&#34;best-technical-books-i-read-in-2020&#34;&gt;Best Technical Books I read in 2020&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://amzn.to/38OqT3l&#34;&gt;Designing Data-Intensive Applications&lt;/a&gt; - An information rich exploration of the technologies behind modern &amp;ldquo;data heavy&amp;rdquo; information systems.  I learned a lot from this and expect that I&amp;rsquo;ll be referencing it regularly in the future&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://amzn.to/3mX7xyd&#34;&gt;Site Reliability Engineering&lt;/a&gt; - A set of essays describing how Google maintains their production systems that has served as a template for the SRE role at other companies.  Was an interesting read, even as I&amp;rsquo;m skeptical of applying &amp;ldquo;gigantic-corp&amp;rdquo; strategies at smaller or less technically savvy companies.  With essays like this I always find it more interesting to understand the problems that companies were seeing and how they approached finding a solution than I am with the details of the final solution, and this book does a good job laying that out.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;best-technical-leadership-books-i-read-in-2020&#34;&gt;Best Technical Leadership Books I Read in 2020&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://amzn.to/3n3xhJb&#34;&gt;How To Measure Anything&lt;/a&gt; - This was a great read on how to think about measuring things that defy easy measurement.  It starts with a lot of great general principals before going into some more technical / detailed topics in the back half of the book.  Most people could probably benefit from reading at least the opening chapters of this book, with the rest open to skimming based on interests.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://amzn.to/382DK2W&#34;&gt;Inspired&lt;/a&gt; - This was probably my favorite &amp;ldquo;work book&amp;rdquo; I read all year.  It&amp;rsquo;s aimed at product managers, but was helpful for me as an engineering manager to understand what &amp;ldquo;great product process&amp;rdquo; looks like and think through how I can work with PMs well and collaborate on our shared goal of building a great product.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://amzn.to/34Z8ZtD&#34;&gt;Making Work Visible&lt;/a&gt; - A breezy walkthrough of the principles behind Kanban.  I don&amp;rsquo;t use Kanban to organize my teams at work, but because of the focus on foundational ideas I still found this bok extremely helpful.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://amzn.to/34ZfBIm&#34;&gt;Team Topologies&lt;/a&gt; - This is pretty specific and nerdy, but for engineering leaders looking to figure out the best way to evolve teams and split off new ones over time as their companies grow and change, this is a great read.  It argues persuasively for the importance of team structure to productivity and product success.  Highly recommended.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;best-non-technical-books-i-read-in-2020&#34;&gt;Best Non-Technical Books I read in 2020&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://amzn.to/3rFWVXQ&#34;&gt;Andrew Carnegie&lt;/a&gt; - A detailed biography of a fascinating historical figure who defied easy characterization.  Carnegie was an immigrant born in poverty who through hard work and good timing became one of the richest men in the world, a union buster who viewed himself as a &amp;ldquo;friend of the workers&amp;rdquo;, a philantropist who wanted to give away his whole fortune, and a political force who aimed for world peace &amp;ndash; and protection for his own interests.  It was a great reminder in the sometimes overly black and white world of 2020 that real humans are complicated and don&amp;rsquo;t fit neatly in our tight political boxes.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://amzn.to/2Juudbc&#34;&gt;Salt, Fat, Acid, Heat&lt;/a&gt; - I&amp;rsquo;m not the primary cook in my family &amp;ndash; I&amp;rsquo;m blessed to regularly enjoy my wife&amp;rsquo;s far superior cooking.  But I enjoy it as an occasional activity and this book helped spark even more interest.  Unlike most cookbooks this book is focused on the science and &amp;ldquo;whys&amp;rdquo; of cooking rather than procedural formulas for making a particular dish.  It felt empowering and exciting rather than my typical frustration with recipes that didn&amp;rsquo;t turn out like the images in the cookbook.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://amzn.to/3aYB87U&#34;&gt;Atomic Habits&lt;/a&gt; -  Over the last few years I&amp;rsquo;ve made a personal transition to focusing more on the habits and routines I&amp;rsquo;m making part of my life and less on ambitious long term goals.  This book gave me a framework for thinking about that transition as well as practical tips for doing it better.  A quick and helpful read.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://amzn.to/3hs4lJM&#34;&gt;How To Talk So Little Kids Will Listen&lt;/a&gt; - An incredibly practical book for how to interact with toddlers.  I&amp;rsquo;ve found a bunch of helpful parenting books, but none beat this for giving parents practical actionable advice that will reduce stress in your house and help you build a relationship with your kids.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://amzn.to/380fM8k&#34;&gt;House of X / Powers of X&lt;/a&gt; - For the comics fans out there, I&amp;rsquo;ve been really enjoying Jonathan Hickman&amp;rsquo;s run on the X-Men, starting with this graphic novel that soft-reboots the whole world of mutants&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>How Teams Go Faster</title>
      <link>https://benmccormick.org/2020/09/04/190000.html</link>
      <pubDate>Fri, 04 Sep 2020 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2020/09/05/190000.html</guid>
      <description>&lt;p&gt;I recently discovered John Cutler&amp;rsquo;s &lt;a href=&#34;https://twitter.com/johncutlefish&#34;&gt;Twitter&lt;/a&gt; and &lt;a href=&#34;https://cutlefish.substack.com/&#34;&gt;blog&lt;/a&gt;.  Everything I&amp;rsquo;ve read from him so far is excellent and highly recommended, but this table in particular felt like it was worth sharing.&lt;/p&gt;
&lt;blockquote class=&#34;twitter-tweet&#34; data-conversation=&#34;none&#34; data-theme=&#34;light&#34;&gt;&lt;p lang=&#34;en&#34; dir=&#34;ltr&#34;&gt;13/13 Feels like fast ... is actually faster &lt;a href=&#34;https://t.co/c87USFeu6b&#34;&gt;pic.twitter.com/c87USFeu6b&lt;/a&gt;&lt;/p&gt;&amp;mdash; John Cutler (@johncutlefish) &lt;a href=&#34;https://twitter.com/johncutlefish/status/1145240762243698688?ref_src=twsrc%5Etfw&#34;&gt;June 30, 2019&lt;/a&gt;&lt;/blockquote&gt; 
&lt;p&gt;It&amp;rsquo;s amazing to me how unhelpful our intuition often is when we&amp;rsquo;re under pressure to speed up.  I&amp;rsquo;ve observed clear examples of several of these items personally over the last several years.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;I&amp;rsquo;ve seen my team go significantly faster &lt;em&gt;with less stress&lt;/em&gt; by shifting projects to being serialized with pairing and collaboration rather than giving everyone their own project &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;I&amp;rsquo;ve watched attempts to get ahead on planning be thwarted by changing business priorities.  This can be frustrating in the moment until you realize the problem is a planning process that can&amp;rsquo;t adapt to new information cleanly.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;I&amp;rsquo;ve been part of another team that doubled in size and then got cut back in half without much discernable impact in actual output over time.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The most effective change my team has made this year has been de-emphasizing filling sprints in favor of being clear about what we&amp;rsquo;re trying to accomplish in the sprint.  I don&amp;rsquo;t think we&amp;rsquo;ve gone far enough in that direction yet.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Some items I&amp;rsquo;d add to John&amp;rsquo;s list:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Manual QA / Deployments &lt;strong&gt;vs&lt;/strong&gt; Test Automation as part of development&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;Senior devs filling up on feature work &lt;strong&gt;vs&lt;/strong&gt; Senior devs mentoring, enabling and unblocking other devs&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;Besides the creative and redundancy benefits of pairing, shared resources like PMs/EMs/QA become bottlenecks as you parallelize.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;This relates to the &amp;ldquo;handing off&amp;rdquo; QA point in John&amp;rsquo;s list.  If the original people responsible for creating the feature aren&amp;rsquo;t writing automation as part of development, there is likely to be inefficiency or gaps in the testing.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;Even worse if this is a manager doing this, something I struggled with as I transitioned from being a &lt;a href=&#34;https://benmccormick.org/2019/03/25/manager-and-developer&#34;&gt;dev-manager hybrid&lt;/a&gt; to managing a larger team.&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>Simple Burnout Triage</title>
      <link>https://benmccormick.org/2020/08/30/190000.html</link>
      <pubDate>Sun, 30 Aug 2020 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2020/08/31/190000.html</guid>
      <description>&lt;p&gt;I have a one question triage process when I’m concerned that I or one of my teammates is headed towards burnout:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If you take the pace &amp;amp; quality of the last 2 months of your life and repeated it again and again, how long would you be able to sustain it?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Why 2 months?  It’s long enough to be a representative sample of your pace and cut out the rush of a specific project deadline or medium sized stressful life event&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.  But it’s a small enough sample to check in regularly, and most people have a fairly clear sense of what their last 2 months have been like for them and can visualize what repeating it would look like.&lt;/p&gt;
&lt;p&gt;When I ask myself or a teammate this question, it tends to elicit one of 3 responses:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;”I can’t go on like this.”&lt;/strong&gt;  The current pace is unsustainable and we’re probably already well into the burnout phase where tasks are being dropped, personal needs are not being met, and everyday life has become overwhelming.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;”I can make this work, but…”&lt;/strong&gt; The most interesting result of this question to me is that it often makes it clear where a priority is being dropped.  “I’m doing good, but I wish I was doing a better job making time for my kids”.  “I’m getting by, but I feel like I only have time for the urgent and I haven’t had a chance to invest in myself”.   “I can do this for a while longer, but I have to figure out a way to live in the moment in the evenings and leave my work at the office”.  The act of visualizing a plausible future often causes people to hone in on what they’re missing.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;”I love my life, and I can keep doing this forever.”&lt;/strong&gt;  If this is where you’re at, treasure it and check in regularly to make sure it’s still the case.&lt;/p&gt;
&lt;h3 id=&#34;what-next&#34;&gt;What next?&lt;/h3&gt;
&lt;p&gt;The question above is laser focused on triage.  Exactly how to handle partial or complete burnout is situation dependent.  But I try to hold to principles of optimizing for the long term and tying my time to my values.  That means while it sometimes may make sense to live in an unsustainable place for a season, I’m always going to weigh that impact on myself, my family and my teammates against the longterm value and take it seriously&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;.  And if my time spent doesn’t line up with my principles and values for a significant length of time, I know it’s time to implement a plan for change.&lt;/p&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;For large life changes like job switches, family emergencies, society-changing pandemics etc it is probably better to assume that short term data is not representative, err on the side of scaling back as needed, and take stock of things on a regular basis.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;A note on taking things on for a season; It’s only a season if it has a defined endpoint or offramp.  If you and your spouse live in different cities to optimize for your career, or you’re working 70 hour work-weeks because your job demands it, and you don’t know when these things will end, you’re not in a season.  This is your life.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>Better than a wild guess</title>
      <link>https://benmccormick.org/2020/08/22/190000.html</link>
      <pubDate>Sat, 22 Aug 2020 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2020/08/23/190000.html</guid>
      <description>&lt;p&gt;I&amp;rsquo;m currently reading Doublas Hubbard&amp;rsquo;s &lt;a href=&#34;https://amzn.to/3lcY3yY&#34;&gt;How To Measure Anything&lt;/a&gt; and it is driving home a point I&amp;rsquo;ve observed anecdotally throughout my career; when people don&amp;rsquo;t know something exactly, they often throw away a ton of things that they do know.  You can see this in project estimation, where engineers often resist providing any estimate since &amp;ldquo;it&amp;rsquo;s hard to tell before we actually build it&amp;rdquo;.  You can see it in product planning, where teams I&amp;rsquo;ve worked with struggle to provide clear usage or business impact goals since &amp;ldquo;it is hard to tell how impactful this will be till we build it&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Hubbard&amp;rsquo;s advice for making properly calibrated estimates would probably help in multiple places in the software world:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Use 90% confidence intervals when there&amp;rsquo;s uncertainty, not point estimates or vague categories like &amp;ldquo;medium risk&amp;rdquo;&lt;/strong&gt; - Saying a piece of software work is &amp;ldquo;large&amp;rdquo; is much less actionable and informative than &amp;ldquo;we&amp;rsquo;re 90% confident that it will take between 3 and 15 days to complete.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use absurd scenarios and alternative bets to calibrate a confidence interval&lt;/strong&gt; - You may think you have no idea how long a novel new software project will take, but even for projects with high uncertainty this is untrue.  You can start by asking questions like &amp;ldquo;is there any chance this will be done tomorrow&amp;rdquo; and &amp;ldquo;is there any chance this project will take more than 5 years&amp;rdquo;.  If the answer is no, then you&amp;rsquo;ve established a baseline confidence interval, and you can start working inward from there.  When you get to the point that something is feasible if unlikely, its a sign that you&amp;rsquo;re probably near the 90% confidence interval&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.  Once you have a starting place, you can further consider a hypothetical bet where you had to choose between a lottery with a 90% payout of $1000 and a scenario where you got the $1000 when the item ended in your range.  If you would clearly prefer one of those scenarios to the other, your range is probably too tight or too loose.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Model your estimates with simple monte carlo simulations&lt;/strong&gt; - Hubbard recommends using Monte Carlo simulations (picking random numbers according to the distributions set up by your confidence intervals ~1000 times) in order to get a better intuition of what real world outcomes might look like.  Doing this right does mean understanding not just the confidence range, but also what the distribution looks like.  Estimating simple software feature work for instance, is likely not a normal distribution.  Many tasks will be straightforward and be completed quickly, but we&amp;rsquo;ll hit occasional tasks that require significant restructuring of a program to complete.  It&amp;rsquo;s a classic &amp;ldquo;long tail&amp;rdquo; scenario.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Break down estimates into component parts&lt;/strong&gt; - One of the most powerful techniques for making better estimates under uncertainty is &amp;ldquo;Fermi Decomposition&amp;rdquo;, the process of breaking an estimation problem into smaller estimation problems (which may be more tractable) and then combining the estimate.  In software this can mean breaking up a large project into the component pieces of work and then estimating those.  Doing this right of course means capturing our uncertainty on the sub-estimates, so that we can roll that up into the larger estimate.  If we optimistically point estimate every element of a project, we&amp;rsquo;re going to end up with a total estimate that is actually less likely, since we need &lt;em&gt;everything&lt;/em&gt; to go well to hit that total estimate.  I commonly see engineers handle this by doing optimistic estimates and then adding a buffer period.  It would be better to be clear about uncertainty and do your decompositions with a range of values (although it does make sense to factor in uncertainty about tasks that may be missing).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Consider what measurements will be valuable&lt;/strong&gt; - When we start viewing our estimation goal as reducing uncertainty rather than eliminating it, its easier to see that some easy measurements might go a long way toward improving our projections, even if they won&amp;rsquo;t take us to an exact value.  For instance if we want to know how many tickets we might close during an upcoming sprint, it can be easy to say that there&amp;rsquo;s no way to know.  The new work is unique and isn&amp;rsquo;t necessarily directly comparable to work we&amp;rsquo;ve done in the past.  However just because we can&amp;rsquo;t make an exact projection doesn&amp;rsquo;t mean we know nothing.  If we look at our last 10 sprints and see how many tasks we completed in each of them, we can feel confident that this upcoming sprint is likely to be between the minimum and maximum value in that range, or at least close.  If we&amp;rsquo;re currently planning like we will accomplish something outside of that range, this could be very useful information.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;All of this definitely has me thinking about the good and bad of software estimation, and how I might incorporate this into my team&amp;rsquo;s rhythms.  Would love to hear stories of effective estimation processes in software.  What do you do that is better than wild guessing?&lt;/p&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;Remember that 90% total interval means that there&amp;rsquo;s a 95% chance that a value is greater than the lower bound and a 95% chance that the value is less than the upper bound.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>The Management Resources I Keep Coming Back To</title>
      <link>https://benmccormick.org/2020/07/24/190000.html</link>
      <pubDate>Fri, 24 Jul 2020 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2020/07/25/190000.html</guid>
      <description>&lt;p&gt;Although I don&amp;rsquo;t read Hacker News much these days, I do subscribe to &lt;a href=&#34;https://hackernewsletter.com/&#34;&gt;a newsletter&lt;/a&gt; that rounds up the best links every week, and there are almost always one or two gems in there.&lt;/p&gt;
&lt;p&gt;This week my favorite link was this roundup of &lt;a href=&#34;https://www.benkuhn.net/progessays/&#34;&gt;Essays on Programming I Think About A lot&lt;/a&gt; by Ben Kuhn, cataloguing essays on the internet that he comes back to or references repeatedly.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m now ~2 years into managing people and because &lt;a href=&#34;https://www.fastcompany.com/90282088/why-being-a-manager-is-a-career-change-not-a-promotion&#34;&gt;Engineering Management is not a promotion&lt;/a&gt;, I&amp;rsquo;ve spent a lot of time leading up to that change and since reading about management in an attempt to avoid being completely clueless at my job&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;Like Ben, I have a few key essays and books that I reference and go back to over and over again.  These are a mix of books and essays that have shaped how I think about the job of engineering leadership.  The books here are mostly well known, while the essays are more obscure, and might be a surprising choice to highlight if you asked their authors.  But each one has taught me something specific that has helped shape my leadership style.&lt;/p&gt;
&lt;h2 id=&#34;essays&#34;&gt;Essays&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://larahogan.me/blog/leadership-style-colors/&#34;&gt;Leadership Style Colors | Lara Hogan&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;It’s totally natural to embody one a lot—that’s your style! But it’s important to be aware of the other styles/approaches available in your leadership toolbox. A strong leader understands that different styles can be valuable when an environment or situation calls for it. As Herminia Ibarra says in my &lt;a href=&#34;https://hbr.org/2015/01/the-authenticity-paradox&#34;&gt;favorite article&lt;/a&gt; on this subject, “Small changes—in the way we carry ourselves, the way we communicate, the way we interact—often make a world of difference in how effectively we lead.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;p&gt;&lt;a href=&#34;https://randsinrepose.com/archives/act-last-read-the-room-and-taste-the-soup/&#34;&gt;Taste The Soup | Rands&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In a meeting where an individual or team is presenting a complex idea or project, my job as the leader is soup tasting. It’s sampling critical parts of the idea to get a sense of how this soup has been or will be made. Who are the critical people? What are the critical parts? Which decisions matter? I don’t know. I do believe that a pre-requisite for leadership is that you have experience. You’ve had trials which have resulted in both impressive successes and majestic failures. These aggregate lessons define your metaphoric soup tasting ability, and when your team brings you a topic to review, it is this experience you apply to ask the critical soup questions.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;p&gt;&lt;a href=&#34;https://charity.wtf/2019/01/04/engineering-management-the-pendulum-or-the-ladder/&#34;&gt;Engineering Management: The Pendulum Or The Ladder | Charity Majors&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If you like engineering management, your tendency is to go “cool, now I’m a manager”, and move from job to job as an engineering manager, managing team after team of engineers.  But this is a trap.  It is not a sound long term plan.  It leads too many people off to a place they never wanted to end up: technically sidelined.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;p&gt;&lt;a href=&#34;https://lethain.com/values-oasis/&#34;&gt;Trapped in a Values Oasis | Will Larson&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The rule of thumb here is to lead through ambiguity, and advocate through disagreement.
It’s important to diagnose your situation correctly, because when you get it wrong, it’ll still feel like you’re making progress, but it’s wholly dependent on you and it’s progress that is likely to come at the cost of undermining both you and your team within the broader organization. It can be extraordinarily frustrating to “disagree and commit” to a policy or value that goes against your personal values, but any worthwhile measure of successful leadership needs to consider your team’s success more highly than your own.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;p&gt;&lt;a href=&#34;https://kellanem.com/notes/friday-wins&#34;&gt;Friday Wins &amp;amp; A Case Study in Ritual Design | Kellan Elliott-McCrea&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Culture is what you celebrate. Rituals are the tools you use to shape culture. Yet very few of us think much about ritual design.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;books&#34;&gt;Books&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://amzn.to/3jyxofc&#34;&gt;Radical Candor | Kim Scott&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“It’s brutally hard to tell people when they are screwing up. You don’t want to hurt anyone’s feelings; that’s because you’re not a sadist. You don’t want that person or the rest of the team to think you’re a jerk. Plus, you’ve been told since you learned to talk, “If you don’t have anything nice to say, don’t say anything at all.” Now all of a sudden it’s your job to say it. You’ve got to undo a lifetime of training. Management is hard.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The best thing I&amp;rsquo;ve read on how to give feedback well.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;a href=&#34;https://amzn.to/2D4btMb&#34;&gt;Death By Meeting | Patrick Lencioni&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The hard truth is, bad meetings almost always lead to bad decisions, which is the best recipe for mediocrity.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;A lot of this book is focused on very specific advice for specific types of meetings, but the philosophical takeaway it left me with was much simpler; meetings aren&amp;rsquo;t non-negotiable things that we all must endure.  They can be designed, and that design matters.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;a href=&#34;https://amzn.to/3f4EvbH&#34;&gt;The Common Rule | James Early&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;All those who want to be attentive to who they are becoming must realize that formation begins with a framework of habits.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is a book written through the lens of the author&amp;rsquo;s Christian faith, so if that bothers you, you might prefer &lt;a href=&#34;https://amzn.to/3jInPdF&#34;&gt;Deep Work&lt;/a&gt;, which covers similar ground in a secular manner.  But for me personally, the rituals and worldview laid out in the Common Rule has been life changing, and has been my most helpful tool as I navigate the &amp;ldquo;Advanced Time Management 501&amp;rdquo; lifestyle of engineering management&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;That&amp;rsquo;s the list for now, but I&amp;rsquo;m sure I&amp;rsquo;ll add more as time goes on.&lt;/em&gt;&lt;/p&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;I would like to think this has worked, but Dunning-Kruger being what it is, I don&amp;rsquo;t know how I could really tell you with confidence.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>Fun with Ascii: Putting some console art on my site</title>
      <link>https://benmccormick.org/2019/12/31/190000.html</link>
      <pubDate>Tue, 31 Dec 2019 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2020/01/01/190000.html</guid>
      <description>&lt;p&gt;I’ve always enjoyed sites that had easter eggs in their consoles, whether they’re simple and whimsical like Ponyfoo.com&lt;/p&gt;
&lt;figure&gt;&lt;br /&gt;
&lt;figcaption&gt;&lt;img style=&#34;display: block; margin-left: auto; margin-right: auto;&#34; title=&#34;acii1.png&#34; src=&#34;https://benmccormick.micro.blog/uploads/2022/23e703419a.png&#34; alt=&#34;Ponyfoo has a “welcome adventurer” message in their console&#34; width=&#34;600&#34; height=&#34;416&#34; border=&#34;0&#34; /&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;or practical like Facebook’s&lt;/p&gt;
&lt;figure&gt;
&lt;figcaption&gt;&lt;br /&gt;&lt;br /&gt;&lt;img style=&#34;display: block; margin-left: auto; margin-right: auto;&#34; title=&#34;ascii2.png&#34; src=&#34;https://benmccormick.micro.blog/uploads/2022/2c27171a3f.png&#34; alt=&#34;Facebook warns people about scams in the console&#34; width=&#34;600&#34; height=&#34;364&#34; border=&#34;0&#34; /&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;I’m also part of a &lt;a href=&#34;https://www.kustomer.com/&#34;&gt;fast growing company&lt;/a&gt; and we’re always hiring, so I thought I’d see if I could leave a fun message in the console, and play around with ASCII art while I was at it.&lt;/p&gt;
&lt;p&gt;Kustomer’s logo is &lt;em&gt;Kusty&lt;/em&gt;; a smily speech bubble with apostrophes for eyes:&lt;/p&gt;
&lt;figure&gt;&lt;img style=&#34;display: block; margin-left: auto; margin-right: auto;&#34; title=&#34;kusty.png&#34; src=&#34;https://benmccormick.micro.blog/uploads/2022/bad1df5ef0.png&#34; alt=&#34;Kustomer logo&#34; width=&#34;600&#34; height=&#34;300&#34; border=&#34;0&#34; /&gt;
&lt;figcaption&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;So how did I get Kusty showing up in the console on this site? I started with a bit of a cheat: I asciified the logo using &lt;a href=&#34;https://www.asciify.me/&#34;&gt;asciify.me/&lt;/a&gt;. That got me a nice starting place, I had an Ascii version of Kusty to work with:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; &#39; ``.&#39;` . -_+&#34;)cTtfyyyszztszszszztzfztfsfzsfzsstttyt17vr&amp;gt;, .   ` &#39;-`- `
  ..`.&#39;`.~)71tyyzzfzfzsyststztyftsytsystyztzzyzsyyytyfsytf1l?!  -.` `&#39;`.
-.- - `+}Tzztsfyffztzzyyztsffyytfyyzztyfzyfzyfystzftszfytfysyt{+--&#39;.- `.
 `--.&amp;gt;Lyffttyztsfyztyt11fYtyyzYTz1yT1yfzfTt1TsYfftsttzzysffssyyt7+  &#39;&#39;`-
 -`!iysttfstffzTi?&#34;+,,!~^~!^__~!_:,:^^^,!~_~~:_,,!:^+/i1zyytfyztzzi~&#39;&#39;-.
. !}tsftzffyTv+~..  -`-.&#39; &#39;. .`-   .&#39;.-- ` ` . -&#39;- .-..~+v1fsfttszf}&amp;lt; . 
 ,xftyyysszv, -. ```&#39; &#39;. .-.``&#39;.-   &#39;&#39;.&#39;--&#39;- &#39;  ` ...&#39;&#39;  .!vytyzsstsx^- 
&#39;/zsstzzzf*` `` &#39;  ` `- &#39;`- ` `.`  -.-   - `.&#39;-- -` - &#39;` &#39;``=1szfyzssi&#39; 
+Yzftsztf? `  `-` ` -- ` &#34;vje4J&amp;gt;&#39; ...` `  &#39;~iteau(.&#39;` `-- ``&#39;/tzszszfY+&#39;
isttsstzl:     `.-  .`&#39;[qQQRgQBt  - `-.&#39; rkDQWRQg6  -&#39;&#39;- `   ^]ffyzstyi&#39;
xyfssytyv&#39;&#39;- .&#39;&#39;-   .:#QBW&amp;amp;j}v+&#39;  &#39;`. `&#39;s@gR@$Lv&#34;-``   - - .&#39;`?ystysztL`
xtyytzsyv .`-.&#39;-  `&#39; JRgBV:...``.&#39; -.  [HWHd+  .&#39;-- `-     &#39;&#39; /ysyzftsl&#39;
cyyfysfyi  &#39;-`&#39;``&#39; -`NBWW^&#39;    .&#39;`` - &#39;2gBQ{`    .-`-&#39;. . `-&#39;.(zsyyzzzL_ 
{ytyztfti    &#39;-`&#39;..&#39;&#39;DBRWSS%9wk&#34;-  .-  nWWHOwE%%5x    `&#39; -  `&#39;|ftzttytx- 
{ttszfysi.`-&#39; `.&#39;&#39; -.DWHgggBRgH2-`.&#39;&#39;  2BWHgWRHgB&amp;amp;&#39; .`. &#39;  . &#39;/sfztfsyc` 
7zzsfsyzi - &#39;`  &#39;&#39; ` &amp;amp;BHgQWRgBHj-&#39;- &#39; &#39;JQWHBBHHHQ@   ` .-```- /ttfttyy7&#39; 
lsfsttfti-&#39;.`  -` -&#39;`DBHgHHRWRHu.. `&#39;`.nWHRgRRBgg&amp;amp;.`&#39;` &#39;`   &#39;-?fsysfss7.
xstfsytti `- `.&#39;&#39;&#39;`.&#39;pBBRQQRBgBn. &#39;&#39; &#39; CQBWBQBBBQO--&#39;`   - -- )sstfzyz] 
}fzztyfsv.  &#39; -   &#39;..+[yfsfyzyv!-    ` !ittfftztc+&#39; &#39;  &#39;  -. &#39;)zzzzstsL`
7ttszfssi&#39;- &#39;-  &#39;`  -``-- - -`` -.-.-`` `` &#39;..- . .&#39;&#39;- .  &#39;.- /sfyyftsL`
{fsyysyzv-&#39; &#39; .-  &#39;`  &#39;    - - -  ```-...&#39; .&#39; -  - .-&#39;`-.&#39;-  `/fstyzszl&#39;
7{yzzyttfi &#39;- &#39;.&#39;.&#39; &#39; &#39; . - - . -&#39;  -&#39;-- &#39;&#39;`  .  -&#39;   `&#39;- .  &#39;`(ffstfss}`
{ztfzttsi -   -&#39; ..&#39;` ``&#39;`.--  .  -. &#39;. .&#39;&#39;&#39;   &#39;  -&#39; -&#39;&#39;.-. &#39; )zssfyzs]-
{tzszzzyi&#39;.&#39;-`.--  &#39; `&#34;&amp;amp;QQQHQWWgHWWgBQWWBggBgWW&amp;amp;/ `` &#39;.&#39; &#39;`- -/zfszzzs}-
xyffzzzsi -.`-`&#39;&#39;&#39;- &#39; &#39;]MHgHRHHgRQHBBWQWHHgBQQO1-`.`&#39;.--. &#39;&#39;` |zzztfysl&#39; 
ittsfsttc^`   -  .&#39;   &#39;`~zMHHQWgBQRQgHQWggHQMt:&#39;&#39; &#39;`- .&#39;   `-,{fttttzzi`
+Yzftsstt|&#39;. .  &#39; .   .  .-vJONHHBWQggBB&amp;amp;MFi. ` &#39; -.  `.&#39;--  \yyzszyf1&amp;gt;`
 /tfyyyzyf&#34;  - `.`&#39;..``  -`- -+\c1f2yTc/&amp;lt;. &#39;``.-`.`&#39;-.&#39;`-&#39;` rfztyssfsi&#39;&#39; 
 :Ltzzytsstv,- ` &#39;.`&#39;  &#39;` &#39; ```- &#39;`    .`.- `&#39;. . - ` ``--,itftfsfyt{,&#39;`  
--^LtfsfsftsYi+:&#39;`-. `  .  .-` - `.--&#39;&#39;`` -   `. ``&#39;`  ~&amp;gt;iTztyyyfzs[&amp;lt; `.
.. ^iftstzzfsssYv)r,^__!_^!!~&#39;.-&#39;. ..- -&#39;&#39; `,_:_~_~:&amp;gt;)i1zsfzsstfzfi!. `-
.`  .&amp;gt;]ytfyyzsyszftsz1TYY1Y11v&amp;gt;-     -.&#39;-&#39;. {TYTTYstzttfzsfftsstl&amp;lt;&#39;   &#39;`
-.-.-. &amp;gt;lfsszzsyytszysyzzzzysfy1?&amp;lt; &#39;       `7zzffsyystzsttztzfx&amp;gt;` &#39; - .&#39;
`.&#39; `&#39;&#39;`.^(c1zfttfztfyssyyffttzyyf}r~.- &#39;&#39;&#39;-7tfyzszzztysfy1L(!-.-`-.`.-`
-&#39;    `&#39; -. !+&#34;([TyyzyzzsztststfsszyYi*_` -`{zyzfzfffT[v&#34;&amp;gt;!&#39;`..`-` .`.-` 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;At this point I could have tossed that into a console.log and called it a day, but I wanted to take this to the next level. And that means color!&lt;/p&gt;
&lt;p&gt;This isn’t something you run into every day while writing for the web, but it turns out that you can apply css to text in the console using a &lt;code&gt;%c&lt;/code&gt; macro. The format goes like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;js&#34;&gt;console.log(&#39;%cbold text %cred text&#39;, &#39;font-weight:bold&#39;, &#39;color: red&#39;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That code outputs &lt;span style=&#34;font-weight: bold;&#34;&gt;bold text&lt;/span&gt; &lt;span style=&#34;color: red;&#34;&gt;red text&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Of course its a pain to split that giant Kusty ascii block into multiple console logs with different colors. So I minimized the pain and wrote a script that would let me take a set of ranges and render characters in one of 3 colors, and using either solid characters &lt;code&gt;A-Za-z1-9+{}&amp;lt;&amp;gt;;&lt;/code&gt; or space characters &lt;code&gt; `.,_-’&lt;/code&gt;. I did eat the cost of writing out the map characters manually based on the generated ascii. If I was going to do this again, I’d probably write out a script to generate the map from the original ascii image, and just fill in the color mappings manually.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;js&#34;&gt;//we use these characters for the solid lines
const solidChars =
  &#39;abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456789+{}&amp;lt;&amp;gt;;&#39;;
// and these ones for empty space
const spaceChars = &#34; `.,_-&#39;&#34;;
&lt;p&gt;// these maps chars and colors
const chars = [spaceChars, solidChars];
const colors = [&#39;#E0E0E0&#39;, &amp;lsquo;#ED6159&amp;rsquo;, &amp;lsquo;black&amp;rsquo;];&lt;/p&gt;
&lt;p&gt;// this is the mapping to generate kusty
const map = [ [13, 0, 0], [45, 1, 1], [13, 0, 0], null, [9, 0, 0], [53, 1, 1] /* etc */ ]&lt;/p&gt;
&lt;p&gt;// generate the ascii string from the map
const ascii = map.reduce((agg, val) =&amp;gt; {
// nulls mean spaces
if (val === null) return agg + &amp;lsquo;\n&amp;rsquo;;
agg = agg += &amp;lsquo;%c&amp;rsquo;;
let characters = chars[val[1]].split(&#39;&#39;);
const randChar = () =&amp;gt;
characters[Math.floor(Math.random() * characters.length)];
for (let i = 0; i &amp;lt; val[0]; i++) {
agg += randChar();
}
return agg;
}, &amp;lsquo;&#39;);&lt;/p&gt;
&lt;p&gt;const colorStrings = map
.filter(x =&amp;gt; x !== null)
.map(
val =&amp;gt; &lt;code&gt;color:${colors[val[2]]}; font-family: monospace, font-weight: bold&lt;/code&gt;
);&lt;/p&gt;
&lt;p&gt;console.log(ascii, &amp;hellip;colorStrings);
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;The code is fairly straightforward, going through each segment and generating a string of random characters based on the map. The interesting parts are probably:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;We use &lt;code&gt;null&lt;/code&gt; to denote new lines. Could have been anything, but null is pretty obvious when you write out the mapping markup.&lt;/li&gt;
&lt;li&gt;I usually use lodash for this, but I wrote some custom code to pull a random item from an array:
&lt;code&gt;const randChar = () =&amp;gt; characters[Math.floor(Math.random() * characters.length)];&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;I added a rare for loop in JavaScript code: even though map/filter/forEach etc work better for most things, a for loop is still the best way to do things when you’re given a number of times you want something to occur.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It works pretty well!&lt;/p&gt;
&lt;figure&gt;&lt;img style=&#34;display: block; margin-left: auto; margin-right: auto;&#34; title=&#34;ascii3.png&#34; src=&#34;https://benmccormick.micro.blog/uploads/2022/12a531a143.png&#34; alt=&#34;A picture of the console on my site&#34; width=&#34;600&#34; height=&#34;550&#34; border=&#34;0&#34; /&gt;&lt;/figure&gt;
&lt;h3 id=&#34;nextsteps&#34;&gt;Next Steps&lt;/h3&gt;
&lt;p&gt;Now that I’ve done this it would be pretty easy to reuse this code to create a terminal Kusty with &lt;a href=&#34;https://github.com/chalk/chalk#readme&#34;&gt;chalk&lt;/a&gt;. Maybe next New Years.&lt;/p&gt;
&lt;p&gt;For everyone else, if this seemed fun to you, you might be interested in the &lt;a href=&#34;https://boards.greenhouse.io/kustomer&#34;&gt;job openings at Kustomer&lt;/a&gt;. Feel free to apply or reach out to me directly if you’re interested in working with us.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>2019 Roundup</title>
      <link>https://benmccormick.org/2019/12/30/190000.html</link>
      <pubDate>Mon, 30 Dec 2019 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2019/12/31/190000.html</guid>
      <description>&lt;p&gt;2019 was the 6th full year of this blog, and it was a bit up and down posting wise.  For the first half of the year I published more or less a post a week, with 24 posts from January till July.  But this is only my 2nd post since then.&lt;/p&gt;
&lt;p&gt;Turns out that starting a new job while learning to be a parent sucks up a lot of time!  I&amp;rsquo;m not making any promises for 2020, but I expect that my writing rate will fall somewhere in between the first 7 months and last 5 months of 2019.  In the meantime, here&amp;rsquo;s a brief look back at the year on the blog.&lt;/p&gt;
&lt;p&gt;This was my first year where I spent the full year managing people, and that was reflected in the blog&amp;rsquo;s topics as well as where I spent my time.&lt;/p&gt;
&lt;h3 id=&#34;most-read-posts-published-in-2019&#34;&gt;Most Read Posts Published in 2019&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://benmccormick.org/2019/02/11/reusable-react&#34;&gt;Reusable Code In React: Inheritance, Composition, Decorators and Mixins&lt;/a&gt; The most popular post for the year was also one of my favorites: a dive into the various mechanisms React provides for reusing code.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://benmccormick.org/2019/01/28/readable-async&#34;&gt;Improving Code Readability With Async/Await&lt;/a&gt; I really like &lt;code&gt;async/await&lt;/code&gt; but its not always clear how to move older patterns to use it.  This was just a quick example of taking some ugly callback code and converting it to use async await.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://benmccormick.org/2019/01/07/the-concerns-of-fe-architecture/&#34;&gt;What&amp;rsquo;s involved in Front End Architecture?&lt;/a&gt;
Another one of my favorite posts to write, this is a look at what types of things developers should be thinking about when they consider front end architecture.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;languages-and-libraries-i-used-a-lot-of-in-2019&#34;&gt;Languages and Libraries I used a lot of in 2019&lt;/h3&gt;
&lt;p&gt;JavaScript (ES6), React (including hooks), PostgreSQL, lodash, Jest, Immer, CSS Modules, Redux,&lt;/p&gt;
&lt;h3 id=&#34;tech-i-want-to-try-in-2020&#34;&gt;Tech I want to try in 2020&lt;/h3&gt;
&lt;p&gt;We&amp;rsquo;re starting to roll out TypeScript at &lt;a href=&#34;https://www.kustomer.com/&#34;&gt;Kustomer&lt;/a&gt; and I&amp;rsquo;m excited to use it in production for the first time.  My code time is more limited these days, so that will probably be my main area for learning as I focus more on helping other people get stuff done.&lt;/p&gt;
&lt;h3 id=&#34;blogs-i-started-following-in-2019&#34;&gt;Blogs I started following in 2019&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://lethain.com/&#34;&gt;Irrational Exuberance! by Will Larson&lt;/a&gt; - a great engineering / technical leadership blog&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;blogs-i-read-every-post-from-in-2019&#34;&gt;Blogs I read every post from in 2019&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://overreacted.io/&#34;&gt;Overreacted by Dan Abramov&lt;/a&gt;, &lt;a href=&#34;https://larahogan.me/&#34;&gt;Lara Hogan&amp;rsquo;s Engineering Leadership blog and newsletter&lt;/a&gt;, &lt;a href=&#34;http://randsinrepose.com/&#34;&gt;Rands In Repose&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;software-i-used-nearly-every-day-in-2019&#34;&gt;Software I used (nearly) every day in 2019&lt;/h3&gt;
&lt;p&gt;MacOS/iOS, Google Search, Chrome/Safari/Firefox, GMail/MailPlane 3, Twitter/Tweetbot, Feedbin/Reeder, iMessage, Slack, Jira, 1Password, VS Code, iTerm, Fish Shell, Github/Bitbucket, Fantastical, Spotify, Bear, CloudApp, Dash, Postman&lt;/p&gt;
&lt;h3 id=&#34;best-technical-books-i-read-in-2019&#34;&gt;Best Technical Books I read in 2019&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://amzn.to/35j1Jq1&#34;&gt;The Pragmatic Programmer 20th Anniversary Edition&lt;/a&gt; - A huge update from the 1st edition, this remains my #1 book recommendation for any professional software developer&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://amzn.to/2QhpkTH&#34;&gt;Accelerate&lt;/a&gt; - A great look at the impact improving devops/release practices can have on software teams/companies&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;best-technical-leadership-books-i-read-in-2019&#34;&gt;Best Technical Leadership Books I Read in 2019&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://abookapart.com/products/resilient-management&#34;&gt;Resilient Management&lt;/a&gt; - A great collection of management wisdom from Lara Hogan.  Nothing revolutionary here for those who already follow her blog/newsletter, but its great to have it all together in one place.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://amzn.to/2QyJLKM&#34;&gt;The Manager&amp;rsquo;s Path&lt;/a&gt; - A super helpful book for anyone thinking about their career path in tech, especially if they&amp;rsquo;re considering management.  Lots of helpful tips for those already managing people as well.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://amzn.to/2ZHbFbx&#34;&gt;An Elegant Puzzle&lt;/a&gt; - Another &amp;ldquo;blog book&amp;rdquo;, this one is a bit of a grab bag of topics, but the content is so high quality it was completely worth it.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://amzn.to/2Fc4izu&#34;&gt;Turn The Ship Around&lt;/a&gt; - Not tech-specific, but one of the best books on leadership I&amp;rsquo;ve read, in the form of a history of a nuclear submarine crew getting ready to deploy.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;best-non-technical-books-i-read-in-2019&#34;&gt;Best Non-Technical Books I read in 2019&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://amzn.to/369CpDX&#34;&gt;I Hear You&lt;/a&gt; - A small practical book on validation that will make you a better friend / spouse / coworker.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://amzn.to/2ZHuM52&#34;&gt;Why We Sleep&lt;/a&gt; - A fascinating book on the (pop) science behind sleep&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://amzn.to/2ZH3bRR&#34;&gt;Team Of Rivals&lt;/a&gt; - A very readable history of the Lincoln presidency focused on his relationships with the other candidates for President in 1860. Incredibly well done.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://amzn.to/2MH6F1e&#34;&gt;Evicted: Poverty and Profit in the American City&lt;/a&gt; - A sobering look at how laws, norms and expectations around rentals and evictions in America contribute to spirals of poverty.  Another very well written book, make sure to read the end to understand the research that went into it and allowed for the very personal feel.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://amzn.to/2sFrDqz&#34;&gt;The Common Rule&lt;/a&gt; - This is a Christian look at how ritual and habit can help us overcome modern distractions and focus on the things that are important.  I&amp;rsquo;ve read a lot of books in this genre in recent years (Deep Work / Indistractable / The Tech Wise Family) and this was my favorite.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://amzn.to/2QyKhsc&#34;&gt;The Foundation Trilogy&lt;/a&gt; - Classic scifi, and a great read. Fascinating to read a mid 1900s view of the future and realize that while space travel and force fields sounded great, it was inconceivable that casual tobacco use in the home might go away.&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>How Software Engineers Produce Value</title>
      <link>https://benmccormick.org/2019/12/17/190000.html</link>
      <pubDate>Tue, 17 Dec 2019 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2019/12/18/190000.html</guid>
      <description>&lt;p&gt;I had the opportunity this week to walk a software engineer who is new to the field through some lessons I&amp;rsquo;ve learned over the years about how software engineers add value to the business.  It seemed generally applicable, so here&amp;rsquo;s a cleaned up version of what I shared.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;what-is-value&#34;&gt;What Is Value?&lt;/h2&gt;
&lt;p&gt;It can be easy to think of software engineering work as a series of task where you&amp;rsquo;re given instructions and you make the computer do what the designer / PM / CEO asked.  Or as a series of fun problem solving challenges that you&amp;rsquo;re somehow getting paid to complete.  Both of those views will eventually lead you to make suboptimal decisions when it comes to helping your business and growing in your role though.  Instead consider the following definition:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Software Developers create value through shipping working code that solves important user problems in a predictable manner.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This captures a number of important things.&lt;/p&gt;
&lt;h3 id=&#34;shipping&#34;&gt;Shipping&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Real Artists Ship - &lt;em&gt;Steve Jobs&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Software Engineer&amp;rsquo;s super power compared to other roles is that we get to build.  We create new things, add new behaviors, and ultimately (for a product company) control the shape of the product our company is built around.  This only has value when software actually ships though.  When we&amp;rsquo;re not shipping, it&amp;rsquo;s actually worse than just being slow to deliver value, because of a few non-obvious factors.&lt;/p&gt;
&lt;p&gt;First, &lt;strong&gt;unshipped code rots.&lt;/strong&gt;  When we leave code in a branch 90% done, it doesn&amp;rsquo;t just stay the same.  It&amp;rsquo;s quite common for our situation to get worse.  Our teammates check in code that may cause merge conflicts, or worse just doesn&amp;rsquo;t take into account the unshipped code and sets us up for subtle bugs.  And when we do get back to the work we&amp;rsquo;ve often lost valuable mental context that makes any remaining work or testing harder and more error-prone.&lt;/p&gt;
&lt;p&gt;Second, &lt;strong&gt;we learn from shipping!&lt;/strong&gt;  It&amp;rsquo;s quite common in software development for a developer or team to complete 90% of their feature according to the spec, only to find that they have another 90% of the work to go.  Doing the work to push things through to production inherently de-risks things, because we learn what the challenges are, and we know how long the work took.  Up until then, we will always have unknowns.  And when software goes out to users, we get to hear their feedback as well.  Shipped software lets us learn from our users (and from the performance of our system) and make adjustments that we wouldn&amp;rsquo;t have known about if we sat on the code.&lt;/p&gt;
&lt;p&gt;So how do we get to shipping?  First, it&amp;rsquo;s important to push things through to completion rather than allowing ourselves to jump from project to project, making progress without finishing, and incurring a lot of cost from context switching.  Soemtimes this may mean imposing kanban style &lt;a href=&#34;https://lethain.com/limiting-wip/&#34;&gt;work in progress limits&lt;/a&gt; on ourselves.  Second, its often helpful to break things into smaller chunks.  Small code reviews are easier to complete, test, &lt;a href=&#34;https://benmccormick.org/2019/04/22/better-code-feedback&#34;&gt;review&lt;/a&gt; and verify.  So multiple small changes will often go through faster than the same changes bundled together into a big chunk.  This can go too far, but as long as your changes work in isolation and provide value, I&amp;rsquo;d encourage erring on this side when in doubt.&lt;/p&gt;
&lt;h3 id=&#34;working-code&#34;&gt;Working Code&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;[We Prefer] working software over comprehensive documentation - &lt;em&gt;The Agile Manifesto&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Software engineers are responsible for their code working.  At the simplest level that means delivering code that doesn&amp;rsquo;t crash when run in the intended way.  As we grow and mature as developers however, we should aspire to  learn to write code that will scale to any reasonable load the system might see (and maybe even to unreasonable loads), code that handles odd input or context gracefully, and code that is easy to modify and maintain.  We should also take responsibility for proving that it works; writing tests, making the code easy to monitor in production, and providing good logging for debugging all fall under a software engineer&amp;rsquo;s domain. We also should make sure that our definition of working matches what the business needs, not just a pedantic reading of whatever spec we&amp;rsquo;re working off of.  More on that in a moment.&lt;/p&gt;
&lt;h3 id=&#34;solving-important-user-problems&#34;&gt;Solving Important User Problems&lt;/h3&gt;
&lt;blockquote class=&#34;twitter-tweet&#34;&gt;&lt;p lang=&#34;en&#34; dir=&#34;ltr&#34;&gt;Just really funny- What the Customer Wanted expanded &lt;a href=&#34;https://t.co/kdr7HKTSDy&#34;&gt;pic.twitter.com/kdr7HKTSDy&lt;/a&gt;&lt;/p&gt;&amp;mdash; Frank Spillers (@farreaching) &lt;a href=&#34;https://twitter.com/farreaching/status/764256002053025792?ref_src=twsrc%5Etfw&#34;&gt;August 13, 2016&lt;/a&gt;&lt;/blockquote&gt;
&lt;p&gt;Software Engineers can be quite inventive in the ways they write code without solving important user problems.  Some common routes:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Working on their own pet projects over the prioritized business problems&lt;/strong&gt; - Tech improvement work and engineer-driven projects are part of a healthy organization, but if they consistently replace work that was scoped based on user requests / feedback, they can cause problems&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Matching the spec without solving the original problem&lt;/strong&gt; - This is partially a design/product problem, but its often possible to meet all the stated requirements for a project without solving the original user pain point.  Great engineers understand exactly what problem they&amp;rsquo;re trying to solve with a feature and will always step back to evaluate whether they&amp;rsquo;re succeeding throughout the development process.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Matching the spec and causing new problems&lt;/strong&gt; - Oftentimes our efforts to fix cause or expose new problems.  When we dodge responsibility by ignoring or hiding those problems instead of openly evaluating tradeoffs or working to improve the solution, we&amp;rsquo;re not providing all the value we&amp;rsquo;re capable of.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;These are ultimately issues of ownership. When we&amp;rsquo;re invested in our work, we will want to work on useful problems and make sure they produce real value.  If you&amp;rsquo;re consistently not feeling that way, it may be time to find something else to work on.&lt;/p&gt;
&lt;h3 id=&#34;in-a-predictable-manner&#34;&gt;In a predictable manner&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;The challenge and the mission are to find real solutions to real problems on actual schedules with available resources - &lt;em&gt;Fred Brooks&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Ok, now we come to the section that is the &lt;em&gt;boring part&lt;/em&gt; for many software engineers.  But as somebody who has recently converted to the management side of the fence, the ability to ship predictably is incredibly important.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s important for software engineers to ship predictably in 2 senses:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;There is ongoing understanding of when something is likely to ship among the people who need to know&lt;/li&gt;
&lt;li&gt;There is ongoing understanding of how something will work when it will ship among the people who need to know.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Estimating software engineering projects is not an exact science. Nobody reasonable expects estimation perfection from software engineers, especially those new to the field.  Instead we aim to be as accurate as possible, and especially to be transparent as those estimates change over time.&lt;/p&gt;
&lt;p&gt;When we encounter obstacles, it&amp;rsquo;s important to be realistic about what they mean to schedules and update the important people in a timely manner.&lt;/p&gt;
&lt;p&gt;For those working on a product team that may be a manager and a PM, for those building something solo, that may be the customers or internal users of the software directly.  It&amp;rsquo;s never fun to say something is going to be late, but its always better to say that we&amp;rsquo;ll miss a date that is 2 weeks away than to tell somebody for the first time that you&amp;rsquo;ve missed the date that was 2 days ago.&lt;/p&gt;
&lt;p&gt;Communicating about the scope of work is just as important as schedule.  If we find out a piece of a feature is unfeasable or we dropped it due to time pressure, its important to communicate that.  Depending on your team/product, that may mean sharing with people directly, updating documentation, or just making the new behavior clear in an interface.&lt;/p&gt;
&lt;h3 id=&#34;its-a-process&#34;&gt;It&amp;rsquo;s a process&lt;/h3&gt;
&lt;p&gt;Nobody starts out their first software engineering job with a fully evolved sense of how to estimate, scope and document their work.  Most have no clue how to think about building a system to be scalable or when to escalate problems to other members of the team.  These are skills learned through hard experience.  Make sure to &lt;a href=&#34;https://benmccormick.org/2019/05/18/obvious-things&#34;&gt;always be reflecting&lt;/a&gt; on what you&amp;rsquo;re experiencing though.  Experience combined with reflection is a powerful mixture, and eventually will lead to growth.  Good luck!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Book Review: Resilient Management</title>
      <link>https://benmccormick.org/2019/07/21/190000.html</link>
      <pubDate>Sun, 21 Jul 2019 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2019/07/22/190000.html</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://abookapart.com/products/resilient-management&#34;&gt;Resilient Management&lt;/a&gt; by Lara Hogan is a short and useful read for engineering managers who want to think more systematically about how they support their team.  Lara covers concepts like how to connect with a new team, how to encourage growth in your teammates, and how to communicate difficult news.  This is a &lt;em&gt;blog+&lt;/em&gt; book: most of the material here has appeared previously in Lara&amp;rsquo;s blog or newsletter, but for the book it has been cleaned up and organized together in a coherent fashion that makes it greater than the sum of its parts.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;ve followed my &lt;a href=&#34;https://benmccormick.org/subscribe&#34;&gt;newsletter&lt;/a&gt; for a while, you&amp;rsquo;ll have seen me link to Lara&amp;rsquo;s work on a regular basis.  Lara’s strength as a teacher is building meaningful exercises for thinking through abstract topics, and that plays out here.  Almost every piece of advice and insight comes with a suggestion on how to start implementing it, or an exercise to help you think deeper about yourself or your situation.  I&amp;rsquo;ve found her &lt;a href=&#34;https://larahogan.me/blog/leadership-style-colors/&#34;&gt;leadership colors&lt;/a&gt; and her &lt;a href=&#34;https://larahogan.me/blog/team-introspection/&#34;&gt;MadLibs worksheet for leadership philosophy&lt;/a&gt; particularly helpful for me.&lt;/p&gt;
&lt;p&gt;In addition to the helpful exercises, the highlights of the book for me were Lara&amp;rsquo;s look at the BICEPS model for understanding people&amp;rsquo;s needs at work, the way she structured her book around a groups evolution over time, and the chapter on communication plans.  I&amp;rsquo;ve made notes to reference each of those areas the next time I hit a relevant situation.&lt;/p&gt;
&lt;p&gt;Overall I&amp;rsquo;d recommend this book to pretty much any early-career engineering manager.  If you&amp;rsquo;re not already familiar with Lara&amp;rsquo;s work, there should be some fantastic new ideas for you in here.  If you have followed it, I recommend buying out of appreciation, and to get the concepts bundled in a nice cleanly organized packages.  These are ideas worth paying for.&lt;/p&gt;
&lt;p&gt;Resilient Management is available from &lt;a href=&#34;https://abookapart.com/products/resilient-management&#34;&gt;A Book Apart&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Avoiding Derived State In React</title>
      <link>https://benmccormick.org/2019/06/23/190000.html</link>
      <pubDate>Sun, 23 Jun 2019 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2019/06/24/190000.html</guid>
      <description>&lt;p&gt;A lot of advice in the React community is focused around avoiding explicitly storing &amp;ldquo;derived state&amp;rdquo; of some type or another.  Some examples of this type of &amp;ldquo;derived state&amp;rdquo; that the community warns against:&lt;/p&gt;
&lt;h4 id=&#34;storing-data-that-is-directly-derived-from-another-piece-of-data-in-redux&#34;&gt;Storing data that is directly derived from another piece of data in redux&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; reducer &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; createReducer(initialState, {
  ADD_USER&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; (state, action) =&amp;gt; {
    state.users &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; [...state.users, action.user];
    &lt;span style=&#34;color:#6272a4&#34;&gt;// numUsers is derived state: it will always be tied to users
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    state.numUsers &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; state.users.length;
  }
})
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;storing-state-that-is-directly-derived-from-a-prop-in-a-component&#34;&gt;Storing state that is directly derived from a prop in a component&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;
&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; Widget &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; props =&amp;gt; {
    &lt;span style=&#34;color:#6272a4&#34;&gt;// the hasError state is derived from the error prop
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; [hasError] &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; useState(&lt;span style=&#34;color:#ff79c6&#34;&gt;!!&lt;/span&gt;props.error);
    &lt;span style=&#34;color:#6272a4&#34;&gt;//... continued ...
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;storing-state-that-is-directly-derived-from-another-piece-of-state&#34;&gt;Storing state that is directly derived from another piece of state&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; NameForm &lt;span style=&#34;color:#ff79c6&#34;&gt;extends&lt;/span&gt; React.Component {
    constructor(props) {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;super&lt;/span&gt;(props);
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.state &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {
            firstName&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;,
            lastName&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;,
            fullName&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;,
        }
    }
    &lt;span style=&#34;color:#6272a4&#34;&gt;// because fullName is directly associated with firstName and lastName, we have to update it
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#6272a4&#34;&gt;// any time they are updated
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    updateFirstName(newFirstName) {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.setState(state =&amp;gt; ({
            ...state,
            firstName&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; newFirstName,
            fullName&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; newFirstName &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39; &amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; state.lastName,
        }))
    }
    updateLastName(newLastName) {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.setState(state =&amp;gt; ({
            ...state,
            lastName&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; newLastName,
            fullName&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; state.firstName &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39; &amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; newLastName,
        }))
    }
    &lt;span style=&#34;color:#6272a4&#34;&gt;// ... continued ....
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;These examples are all based on real-world code I&amp;rsquo;ve seen.  And they all were in code that &lt;em&gt;worked&lt;/em&gt;, the program executed as expected.  But they&amp;rsquo;re still problematic.  This type of derived state is error-prone; when new code is written to update the state, each new programmer touching the code has to understand the relationship, or the whole thing can get out of sync.  When state is coming from props, like the error example above, you have to make sure that the state gets updated properly when the props change. And when the state gets out of sync, it is possible to end up in strange states where a programmer&amp;rsquo;s expectations are violated.  A program shows a blank state saying no users have been added, even though one has already been created. A form is expecting to have an error, but the error text is empty or set to a default value.  Or a site has 2 different names for an individual that show up differently in separate parts of the interface.&lt;/p&gt;
&lt;p&gt;This type of problem isn&amp;rsquo;t a new thing in Computer Science.  When programmers do it by accident they usually call it a &lt;a href=&#34;https://en.wikipedia.org/wiki/Don%27t_repeat_yourself&#34;&gt;DRY violation&lt;/a&gt;.  When they do it intentionally they call it caching.  And when they do it intentionally but screw things up, they &lt;a href=&#34;https://twitter.com/secretGeek/status/7269997868&#34;&gt;make jokes about off by one errors&lt;/a&gt;.  Fortunately, that means that the tradeoffs are pretty well understood here.  So how do we handle situations where it looks like derived state may be necessary?&lt;/p&gt;
&lt;h4 id=&#34;just-derive-state-at-render-time&#34;&gt;Just Derive State At Render Time&lt;/h4&gt;
&lt;p&gt;For many many things, including the 3 examples above, if you need information at render time that can be derived from other pieces of state, it&amp;rsquo;s totally fine to just calculate it at render time.  For the first name example above, you can just include a &lt;code&gt;let fullName = this.state.firstName + &#39; &#39; + this.state.lastName;&lt;/code&gt; line at the top of your render function and move on&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;. Storing derived information is unnecessary and harmful when calculating it at runtime adds minimal performance overhead or repetition.&lt;/p&gt;
&lt;h4 id=&#34;memoization&#34;&gt;Memoization&lt;/h4&gt;
&lt;p&gt;But Ben, my component is slow now!&lt;/p&gt;
&lt;p&gt;&amp;hellip;are you sure it&amp;rsquo;s actually slow?  Have you tested it?  Have you proven that the derived state calculation is actually a meaningful part of this?&lt;/p&gt;
&lt;p&gt;Deriving state can be slow when you have to do complicated calculations or reformatting of data.  This is still not usually a problem, but if you&amp;rsquo;re in a performance sensitive area of code and have proven it to be a problem, you can start considering caching solutions. You still don&amp;rsquo;t want to store your cached values in state or your redux stores though.  Instead, you want to use a computed value that is recalculated when its inputs change.  The exact code will depend on your state management strategy, but some examples out there include&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/reduxjs/reselect&#34;&gt;Reselect for Redux&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://mobx.js.org/refguide/computed-decorator.html&#34;&gt;Computeds in MobX&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://reactjs.org/docs/hooks-reference.html#usememo&#34;&gt;useMemo in React Components&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All of these methods use &lt;em&gt;memoization&lt;/em&gt;, a type of caching where arguments are passed to a function, and if the function has been called with those arguments before, it returns the previous result rather than recomputing.  If for instance we had a component and wanted to get the names of all &lt;code&gt;users&lt;/code&gt; with the current &lt;code&gt;type&lt;/code&gt; based on props, and we knew that &lt;code&gt;users&lt;/code&gt; was sometimes quite large, making the calculations slow, and we expected the component to re-render often for some reason or another we might write code like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; UsersList &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; ({users, type,}) =&amp;gt; {

    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; userNames &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; useMemo(() =&amp;gt; users.map(user =&amp;gt; user.type &lt;span style=&#34;color:#ff79c6&#34;&gt;===&lt;/span&gt; type), [users, type]);
    &lt;span style=&#34;color:#6272a4&#34;&gt;// ... continued ...
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now userNames will automatically be recalculated only when users or type changes&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;.  The MobX and Redux solutions work similarly.  Memoization isn&amp;rsquo;t a performance silver bullet: at some point, you might have to look at how you can make your calculations less expensive or take them off of the rendering path completely.  But for most simple data transformation tasks, deriving state at render time and using memoization to keep it performant where needed should help you tame any derived state problems you encounter.&lt;/p&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;But you should probably read about all the ways that &lt;a href=&#34;https://www.kalzumeus.com/2010/06/17/falsehoods-programmers-believe-about-names/&#34;&gt;names can be more complicated than you think&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;Note that useMemo (and most memoization solutions generally) doesn&amp;rsquo;t guarantee the function will never run more than once.  Most solutions have a limited number of results they will store, so if the inputs change often, the result might get recalculated.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>Lessons From Managing A Distributed Team</title>
      <link>https://benmccormick.org/2019/06/16/190000.html</link>
      <pubDate>Sun, 16 Jun 2019 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2019/06/17/190000.html</guid>
      <description>&lt;p&gt;Working with people over the internet is different from meeting in an office five days a week.  This isn&amp;rsquo;t a moral statement.  I&amp;rsquo;ve done and enjoyed both.  Working with a distributed team requires a different set of skills, especially when you&amp;rsquo;re a leader.  Today I want to share the most helpful lessons I&amp;rsquo;ve learned over the last year managing a distributed team.&lt;/p&gt;
&lt;h4 id=&#34;evaluate-process-and-outcomes-not-inputs&#34;&gt;Evaluate process and outcomes, not inputs&lt;/h4&gt;
&lt;p&gt;Focusing on output` is great advice for any team, but it&amp;rsquo;s easier and more important when managing remote teams.  When you&amp;rsquo;re not in the office with people, you won&amp;rsquo;t see when they start in the morning or finish at night.  You won&amp;rsquo;t be able to tell if they&amp;rsquo;re taking long coffee breaks or checking Amazon between tasks.  You&amp;rsquo;ll have to evaluate them on their output and on the methods they use to get work done.&lt;/p&gt;
&lt;p&gt;Evaluating on outputs is tricky for tech work in the short term.  It&amp;rsquo;s often hard to tell how hard a specific task should have been.  But over the long run, you&amp;rsquo;ll need to find ways to see if developers are meeting their goals, and focus on that over the exact times they did work.  And this is good, because that is actually what matters.&lt;/p&gt;
&lt;p&gt;Output is a lagging indicator though.  In the short term, what you can evaluate if &amp;ldquo;butts in seats&amp;rdquo; isn&amp;rsquo;t an option.  I recommend process: is work being documented, are tests being written and are code reviews being done in a timely manner?  The nice thing about this is that you can check these things in low touch ways; by reviewing your issue tracking and version control systems rather than having status meetings or sending distracting slack messages.  This idea comes up in &lt;a href=&#34;https://amzn.to/2XBg1iv&#34;&gt;Camille Fournier&amp;rsquo;s book The Manager&amp;rsquo;s Path&lt;/a&gt;, where she argues persuasively for always doing your information gathering in ways that don&amp;rsquo;t disrupt your team first.&lt;/p&gt;
&lt;h4 id=&#34;1-1s-are-extra-important&#34;&gt;1-1s are extra important&lt;/h4&gt;
&lt;p&gt;Let&amp;rsquo;s say Sarah has some lingering concerns about her current project that she&amp;rsquo;s not yet ready to raise to the full group.  When I work in the same office with Sarah, she can drop by my desk anytime to talk through a small issue.  When we&amp;rsquo;re working remotely, that may not feel as comfortable for a variety of reasons.  Good 1-1s provide space for the little things to come out.&lt;/p&gt;
&lt;h4 id=&#34;when-you-get-in-person-time-focus-on-the-relationship&#34;&gt;When you get in-person time, focus on the relationship&lt;/h4&gt;
&lt;p&gt;Currently I get together with my team (and my manager) about once a quarter.  Initially my instinct was to save the &amp;ldquo;big work stuff&amp;rdquo; for that time.  And I still try to get a few big conversations in each time, mostly around career development.  But the most value from these visits has come in the gaps, when I go out to lunch with my team and chat, or we get together with a larger group after work.  Time spent together builds trust, and that trust lingers and pays off when you&amp;rsquo;re back on the other side of the internet the next week.&lt;/p&gt;
&lt;h4 id=&#34;async-communication-is-great--dont-neglect-face-to-face-time&#34;&gt;Async communication is great.  Don&amp;rsquo;t neglect &amp;ldquo;face to face&amp;rdquo; time.&lt;/h4&gt;
&lt;p&gt;&amp;ldquo;Embrace async communication&amp;rdquo; is common remote work advice.  When you get stuff done through email/slack/Github/Invision/etc you have fewer meetings and more flow time for your team.  Which is great!  My team takes advantage of &amp;ldquo;async&amp;rdquo; tools every day.  But I also try to be intentional about working in &amp;ldquo;face to face&amp;rdquo; time through Zoom.  For my team that&amp;rsquo;s a daily standup and weekly 1-1s, but it could be different for another team&amp;rsquo;s process.  The key is to not &lt;em&gt;only&lt;/em&gt; rely on writing.  Writing is an amazing way to communicate, but it will always lack the context of the human face.  For now I&amp;rsquo;m aiming for a mix of mostly async with regular &amp;ldquo;internet face to face&amp;rdquo;, and occasional &amp;ldquo;in person&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Make sure to personalize your communication as well.  If Jerry tends to miss all nuance when you communicate in text, try to spend more time talking over zoom to make sure you&amp;rsquo;re communicating.  On the other hand if Jennifer has a tendency to lose track of what you&amp;rsquo;re asking her to do, you may want to give instructions through a text medium, where you can use it for accountability later.&lt;/p&gt;
&lt;h4 id=&#34;hire-for-remote-success&#34;&gt;Hire for remote success&lt;/h4&gt;
&lt;p&gt;Not everyone is going to thrive in a remote role.  Most companies hiring remote recognize this and try to filter for it in some form. A lot of companies&#39; response here is to &amp;ldquo;only hire senior&amp;rdquo;.  Which is probably a workable heuristic in some ways.  Developers that have a proven track record of success probably have built up some habits that will help them succeed in remote work even if they aren&amp;rsquo;t naturally inclined to it.  But hiring only senior folks is expensive, and makes things like diversity and career growth paths harder.&lt;/p&gt;
&lt;p&gt;I haven&amp;rsquo;t done this enough to draw any hard conclusions on remote hiring yet.  But the qualities I want to evaluate for are independence, technological comfort, writing skills, and a history of taking the initiative to seize opportunities (in whatever domain).  Obviously that&amp;rsquo;s in addition to normal hiring criteria.&lt;/p&gt;
&lt;h4 id=&#34;tools-and-process-matter&#34;&gt;Tools and Process matter&lt;/h4&gt;
&lt;p&gt;The worst way to work remote is to not commit to it.  Commitment means aligning your process toward remote work.  Some lessons here.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;First, Hybrid meetings are harmful to your team&lt;/strong&gt;.  There are 3 ways to do meetings: in person, remote, or hybrid.  An in person meeting involves putting a number of humans in a small room for an hour and letting them talk through an issue.  A remote meeting connects various people from the comforts of whatever work venue they&amp;rsquo;ve chosen, and discussion ensues over the internet.  In a hybrid meeting, some people are in the room, and some are connecting remotely.  Hybrid meetings are hell for the remote folks.  Usually they can&amp;rsquo;t hear at least one person well.  They can&amp;rsquo;t match faces to voices, lose context of what is happening in the room, and are sometimes just plain ignored by the folks in the room.&lt;/p&gt;
&lt;p&gt;I really didn&amp;rsquo;t understand how bad this was until I did it myself a few times.  If you&amp;rsquo;re a leader who uses or tolerates hybrid meetings, I highly recommend trying to call into them remotely a few times.  As the boss you&amp;rsquo;ll get a slightly different experience, but ask yourself: are you a first class meeting participant when you&amp;rsquo;re calling in remote?  If not, is it acceptable to you to treat your remote workers as second class participants?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Second, Use good tools&lt;/strong&gt;.  Bad collaboration software is a drag if you&amp;rsquo;re working with people in person.  It&amp;rsquo;s a killer for remote teams.  Use software that lets you communicate in timely and useful ways, keep your project critical information organized, and lets your team focus on getting stuff done.  There are hundreds of good tools out there these days, so there&amp;rsquo;s no excuse for using bad ones.  My recommendations, which are not particularly controversial and also not the only good options: use Zoom for video chat, Slack for messaging, Bitbucket, GitHub, or Gitlab for Version Control, Trello or Jira&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; for task tracking depending on the size of your team, and Google Drive for keeping documents and documentation together&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;I&amp;hellip; don&amp;rsquo;t love Jira.  But Trello doesn&amp;rsquo;t scale forever, and I haven&amp;rsquo;t seen anything significantly better than Jira for large teams.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;My team doesn&amp;rsquo;t actually use Google Docs for documentation, we use Confluence.  Which is&amp;hellip; worse than Jira.  So this is more of a &amp;ldquo;don&amp;rsquo;t be miserable like me&amp;rdquo; recommendation than one based on experience.  I&amp;rsquo;d be curious to hear if anyone has a documentation/wiki tool that they love.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>Book Review: The Manager&#39;s Path</title>
      <link>https://benmccormick.org/2019/06/11/190000.html</link>
      <pubDate>Tue, 11 Jun 2019 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2019/06/12/190000.html</guid>
      <description>&lt;p&gt;Titles in the software engineering world are strange.  Without much work, it&amp;rsquo;s easy to find &lt;em&gt;Senior Engineers&lt;/em&gt; with 2 years of professional experience, &lt;em&gt;junior developer&lt;/em&gt; job descriptions requesting 5 years of experience, &lt;em&gt;tech lead&lt;/em&gt; roles focused purely on technology, &lt;em&gt;tech lead&lt;/em&gt; roles where the lead is managing a team, and who can tell the difference between a &lt;em&gt;CTO&lt;/em&gt; and a &lt;em&gt;VP of Engineering&lt;/em&gt; anyway?  This results in weird title shifts when developers switch jobs, odd or unfair salary distributions, and a world where it is very difficult to understand what a career path looks like in this industry.&lt;/p&gt;
&lt;p&gt;Camille Fournier&amp;rsquo;s book &lt;a href=&#34;https://amzn.to/2F2jG1p&#34;&gt;The Manager&amp;rsquo;s Path&lt;/a&gt; steps into this breach by laying out a clear look at an engineering management-focused career path. The book runs through a series of roles: &lt;em&gt;Mentor&lt;/em&gt; to &lt;em&gt;Tech Lead&lt;/em&gt; to &lt;em&gt;Manager&lt;/em&gt; to &lt;em&gt;Manager of Managers&lt;/em&gt; all the way up to &lt;em&gt;Executive&lt;/em&gt;. For each role she describes what the job is,  walks through what type of challenges you might face in the role after a promotion, and offers practical advice on overcoming those challenges.&lt;/p&gt;
&lt;p&gt;I found it to be an extremely engaging read, and the best description of what it actually looks like to advance in technical leadership roles I&amp;rsquo;ve ever read.  Because she focuses on skills and responsibilities more than titles, it&amp;rsquo;s possible to apply her advice across large and small companies, even those with wonky title structures.  It helped me think about what skills I need to be building in my career, and gave me a glimpse of what next steps look like.&lt;/p&gt;
&lt;p&gt;The focus on common challenges and how to face them was also helpful, though whole books could (and have) been written on those challenges and how to face them at each level.  The Manager&amp;rsquo;s Path serves as a good starting point here, identifying the challenges and giving good solid general advice for facing them.  For those new to a role it could help them identify where they&amp;rsquo;re weak or uncomfortable, and serve as a starting point to a deeper dive into those areas.&lt;/p&gt;
&lt;p&gt;As I read the book, I immediately thought of 4 or 5 people at various points in their career I knew who could benefit greatly from reading this book.  If you&amp;rsquo;re working in the software world and think that you long term are interested in advancing in your career beyond your current role, there will probably be interesting tidbits in here for you.  Even those who are sure they &lt;strong&gt;don&amp;rsquo;t&lt;/strong&gt; want to be in management could benefit from understanding the perspectives of what engineering managers actually &lt;em&gt;do&lt;/em&gt;.  The book is also structured so that the first few chapters are highly relevant for both technical and manager track developers; tech lead is an important role on both tracks.  If you fall into one of those buckets, I highly recommend &lt;a href=&#34;https://amzn.to/2F2jG1p&#34;&gt;The Manager&amp;rsquo;s Path&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Thinking About Values</title>
      <link>https://benmccormick.org/2019/06/02/190000.html</link>
      <pubDate>Sun, 02 Jun 2019 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2019/06/03/190000.html</guid>
      <description>&lt;p&gt;As a way to help myself grow in my first year as a manager, I’ve been working through &lt;a href=&#34;https://rework.withgoogle.com/guides/managers-develop-and-support-managers/steps/review-googles-new-manager-training/&#34;&gt;Google’s New Manager Training&lt;/a&gt; which they have generously published online. One exercise that stood out to me was a “values selection” process, where they encourage managers to select a ranked list of 5–10 words that resonate with them as values from a list of around 400 “values words”.&lt;/p&gt;
&lt;figure&gt;&lt;br /&gt;
&lt;figcaption&gt;&lt;img style=&#34;display: block; margin-left: auto; margin-right: auto;&#34; title=&#34;values.png&#34; src=&#34;https://benmccormick.micro.blog/uploads/2022/a60c2dad3d.png&#34; alt=&#34;A list of 400 values words like accountability, accuracy, achievement, altruism and more&#34; width=&#34;596&#34; height=&#34;573&#34; border=&#34;0&#34; /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Choosing values is an odd process, because you’re choosing between “goods”. When I first went through this sheet, I circled over 40 words as values that “resonated” with me. They’re things that I value and strive for, or wish that I was more like. Deciding between adventurousness and cowardice is not a “values decision”. A real values decision means that you’re trying to decide whether good traits like adventurousness, belonging, or clear-mindedness are more important to you.&lt;/p&gt;
&lt;p&gt;Management often forces you to choose between goods: Will we ship quicker? Aim for higher quality? How do those choices impact work/life balance for our teams?. It’s hard to know if we’re making good choices, because the results routinely lack clarity. Indicators lag, causation is fuzzy, and we don’t get to compare to a control group. Values can be guideposts through ambiguity. I’ve seen the power of this at a company level in my current gig, where having a set of values that are kept in the spotlight often allows us to weaponize them as decision making tools &lt;a id=&#34;fnref:1&#34; class=&#34;footnote&#34; title=&#34;see footnote&#34; href=&#34;#fn:1&#34;&gt;[1]&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Going through the list, I eventually cut things down to 20, 12, 10 and then 8. That still feels like a lot to me, but for each of the 8 I can easily cite work situations I’ve faced in the past month where my response came directly out that value. In the end I ended up with &lt;em&gt;Integrity&lt;/em&gt;, &lt;em&gt;Thankfulness&lt;/em&gt;, &lt;em&gt;Community&lt;/em&gt;, &lt;em&gt;Prudence&lt;/em&gt; (in the &lt;a href=&#34;https://en.wikipedia.org/wiki/Prudence&#34;&gt;classical sense&lt;/a&gt;), &lt;em&gt;Generosity&lt;/em&gt;, &lt;em&gt;Continual Improvement&lt;/em&gt;, &lt;em&gt;Accountability&lt;/em&gt;, &lt;em&gt;Justice&lt;/em&gt;. I find that these are easy to connect to my everyday work when I write them out as more detailed sentences though.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Act with &lt;em&gt;integrity&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Live with &lt;em&gt;thankfulness&lt;/em&gt; for what I’ve been blessed with.&lt;/li&gt;
&lt;li&gt;I want to work and live life in &lt;em&gt;community&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Make decisions based on a rational analysis of reality, not feelings and first impressions (&lt;em&gt;Prudence&lt;/em&gt;).&lt;/li&gt;
&lt;li&gt;Don’t save it all for myself. Leave margin and be &lt;em&gt;generous&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Continual Improvement&lt;/em&gt; + Goodism are a powerful combo&lt;a id=&#34;fnref:2&#34; class=&#34;footnote&#34; title=&#34;see footnote&#34; href=&#34;#fn:2&#34;&gt;[2]&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Be &lt;em&gt;accountable&lt;/em&gt; for my responsibilities and hold others to the same.&lt;/li&gt;
&lt;li&gt;Actively work for &lt;em&gt;justice&lt;/em&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I’ve published them &lt;a href=&#34;https://benmccormick.org/my-values&#34;&gt;here&lt;/a&gt; with a bit more detail.&lt;/p&gt;
&lt;p&gt;Those are “guideposts” that I can easily quote to myself or post up somewhere, but they still have enough substance to say something meaningful when I’m considering how to handle a low-performing employee, organizational changes, or personal career decisions. I’ve already seen these values bring a clarity to my thinking about tough things in a short period of time. If you’re interested, I highly recommend checking out &lt;a href=&#34;https://rework.withgoogle.com/guides/managers-develop-and-support-managers/steps/review-googles-new-manager-training/&#34;&gt;Google’s training&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34;&gt;&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;I’ve also seen how quickly this becomes useless when those values are not universally embraced or enforced. &lt;a class=&#34;reversefootnote&#34; title=&#34;return to article&#34; href=&#34;#fnref:1&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;Probably a separate post, but &lt;em&gt;goodism&lt;/em&gt; has always been my response when asked if I’m a perfectionist: “I’m a goodist. I care about doing work that is good and meets the needed standards, but tend to move to the next challenge when I pass that bar and hit diminishing returns”. &lt;a class=&#34;reversefootnote&#34; title=&#34;return to article&#34; href=&#34;#fnref:2&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Herding Lions</title>
      <link>https://benmccormick.org/2019/05/26/190000.html</link>
      <pubDate>Sun, 26 May 2019 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2019/05/27/190000.html</guid>
      <description>&lt;p&gt;I used to find myself using the term &amp;ldquo;herding cats&amp;rdquo; a lot when confronting inertia, disorganization or ambiguity in work situations.  &lt;a href=&#34;https://www.urbandictionary.com/define.php?term=herding%20cats&#34;&gt;Urban Dictionary&lt;/a&gt; actually endorses this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The phrase herding cats comes from the common saying that something involving coordination of many different groups or people is as difficult as herding cats. One of the commonly encountered uses of the term in technical fields is the phrase &amp;ldquo;Managing programmers is like herding cats&amp;rdquo; or &amp;ldquo;Managing engineers is like herding cats&amp;rdquo;. In education it would be &amp;ldquo;Managing students is like herding cats&amp;rdquo;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The phrase correctly captures the difficulty of getting a group of programmers (or even worse &lt;em&gt;teams of programmers&lt;/em&gt;) on the same page.  But there&amp;rsquo;s an inherent arrogance to it.  The implication is that the herder is the adult in the room and everyone else&amp;rsquo;s pointless individualism is getting in the way.&lt;/p&gt;
&lt;p&gt;There are days that I think I could fix everything if I could just get the *&amp;amp;$% cats to move in the right direction.  In those situations  I&amp;rsquo;ve started telling myself that what I&amp;rsquo;m actually doing is herding &lt;strong&gt;lions&lt;/strong&gt;.  How do you herd a group of lions?  I have no idea.  But I know that if you don&amp;rsquo;t start with a healthy respect for the lion&amp;rsquo;s capabilities and agenda, it won&amp;rsquo;t end well for you.&lt;/p&gt;
&lt;p&gt;When you treat people like lions, it&amp;rsquo;s an opportunity to stop and figure out &lt;em&gt;why&lt;/em&gt; they&amp;rsquo;re not just getting on board with your &lt;em&gt;obvious&lt;/em&gt; plan.  It&amp;rsquo;s an opportunity to learn, to find new ways to motivate people, and maybe even to empower somebody who had been viewing themselves as more of a kitten.  Ultimately the best teams flourish where people can &lt;a href=&#34;https://rework.withgoogle.com/blog/five-keys-to-a-successful-google-team/&#34;&gt;be strong contributors, take risks and do work they find meaningful&lt;/a&gt;.  They&amp;rsquo;re teams of lions.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Obvious Things</title>
      <link>https://benmccormick.org/2019/05/17/190000.html</link>
      <pubDate>Fri, 17 May 2019 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2019/05/18/190000.html</guid>
      <description>&lt;p&gt;I saw a tweet thread a few weeks ago that made me think:&lt;/p&gt;
&lt;blockquote class=&#34;twitter-tweet&#34;&gt;&lt;p lang=&#34;en&#34; dir=&#34;ltr&#34;&gt;There’s a bit of a meme in some parts that there is value in saying, out loud, “I realize that I am surprised.” For similar reasons, I often subvocalize “I believe I now understand the type of situation the ‘trivial’ advice was preparing me for.” &lt;a href=&#34;https://t.co/JzdYmSvJWH&#34;&gt;https://t.co/JzdYmSvJWH&lt;/a&gt;&lt;/p&gt;&amp;mdash; Patrick McKenzie (@patio11) &lt;a href=&#34;https://twitter.com/patio11/status/1115751939210223616?ref_src=twsrc%5Etfw&#34;&gt;April 9, 2019&lt;/a&gt;&lt;/blockquote&gt;
&lt;blockquote class=&#34;twitter-tweet&#34;&gt;&lt;p lang=&#34;en&#34; dir=&#34;ltr&#34;&gt;And then you repeat it to someone and they say “lol that is obvious” and you wonder if you know the advice well enough yet to correct them on how not obvious it is going to be for their next 10 years.&lt;/p&gt;&amp;mdash; Patrick McKenzie (@patio11) &lt;a href=&#34;https://twitter.com/patio11/status/1115752453910061056?ref_src=twsrc%5Etfw&#34;&gt;April 9, 2019&lt;/a&gt;&lt;/blockquote&gt;
&lt;p&gt;I realized that I&amp;rsquo;ve encountered plenty of pieces of wisdom in my software career that have this property; I see them as clear and obvious when put in the abstract, but only learn to actually apply them by repeatedly failing to do so.  This is what people talk about when they say something is &amp;ldquo;hard earned experience&amp;rdquo; I guess.&lt;/p&gt;
&lt;p&gt;Here are some examples from my career:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;In the long run, rate of improvement (or regression) matters more than current level&lt;/strong&gt; - This has applications in hiring, code quality, and finding/staying in a job.  But it&amp;rsquo;s often easier to observe how good something is now than to see how its changing, and I often fail to properly estimate what a trend means for a situation 1-3 years down the road.  It&amp;rsquo;s also easy to mis-apply this principle when you for get about the &amp;ldquo;long run&amp;rdquo; part.  A new employee with tons of potential won&amp;rsquo;t help you when you need an experienced hand &lt;em&gt;now&lt;/em&gt; and fixing technical debt can easily cost you your ability to hit a quarterly objective.  Knowing how to balance these long and short term goals is something I still struggle with all the time.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rewriting from scratch is (almost) never worth it&lt;/strong&gt; - &lt;a href=&#34;https://www.joelonsoftware.com/2000/04/06/things-you-should-never-do-part-i/&#34;&gt;Joel Spoelsky&lt;/a&gt; wrote about this way back in 2000 and I remember reading that article nearly a decade ago and nodding along.  I seem to have infinite capacity to convince myself that my current situation fits in those parentheses though.  In my career this has mostly been a problem where I&amp;rsquo;m able to more accurately forecast the pain that would ensue from fixing what exists (because that code exists and is easier to work with), while I appear to systematically underestimate the pain of building the new thing (because the internet told me it would be great, and the code doesn&amp;rsquo;t exist for me to nitpick yet).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Always consider multiple options&lt;/strong&gt; - Pretty much any decision (technical or otherwise) benefits from having multiple contenders.  This seems obvious.  But I have often let myself fall into situations where I&amp;rsquo;m choosing between just 2 options, or really just choosing whether or not to do 1 thing.  This has applications in technology choices, job choices, responding to another person&amp;rsquo;s provocations, and more.  I intuitively know that more options are good, and I constantly miss opportunities to add options.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;So how do we improve on these situations where we fail to apply &lt;em&gt;obvious&lt;/em&gt; wisdom?  I&amp;rsquo;ve been learning a few things lately.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Always review what you&amp;rsquo;ve done on a regular basis&lt;/strong&gt; - Do weekly reviews about how your week went.  Do quarterly reviews with yourself about how your job is going.  When you make big decisions, make sure to find a time to check back in later and evaluate how it went.  We make better decisions when we take the time to measure our results&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Note Missed Opportunities&lt;/strong&gt; - When you do those reviews, make sure to pay attention to when you missed an opportunity to apply something you &lt;em&gt;knew&lt;/em&gt;.  Sometimes we make mistakes because we just didn&amp;rsquo;t know something.  It&amp;rsquo;s more common though that we didn&amp;rsquo;t properly apply our own principles and knowledge.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Identify Cues&lt;/strong&gt; - Identify the thing that you know you&amp;rsquo;re going to have to handle different next time.  Maybe you say &amp;ldquo;if I&amp;rsquo;m looking for a job, I should consider at least 4 or 5 different companies and not focus in on just one&amp;rdquo;, or if I&amp;rsquo;m asked to fix a legacy codebase, I will spend at least 3 months trying to improve it before considering a re-write,and I&amp;rsquo;ll look for real world comparisons to base a rewrite estimate on&amp;quot;.  Whatever it is for you, when you can identify situations where a specific action should take place, it can help you be better the next time instead of repeating the same old mistakes.&lt;/li&gt;
&lt;/ol&gt;
</description>
    </item>
    
    <item>
      <title>How To Get Better Feedback On Your Code</title>
      <link>https://benmccormick.org/2019/04/21/190000.html</link>
      <pubDate>Sun, 21 Apr 2019 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2019/04/22/190000.html</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Deliberate practice &lt;a href=&#34;1&#34;&gt;is when&lt;/a&gt; your attention is focused tightly on a specific skill you’re trying to improve &lt;a href=&#34;2&#34;&gt;…&lt;/a&gt; &lt;strong&gt;you receive feedback so you can correct your approach to keep your attention exactly where it is most productive.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Cal Newport, Deep Work&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt; &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In &lt;a href=&#34;https://amzn.to/2TqwDeR&#34;&gt;Deep Work&lt;/a&gt;, Cal Newport explains that research has shown the primary difference between experts and amateurs in a typical field is not innate talent; instead it is the amount of time they’ve spent in &lt;em&gt;Deliberate Practice&lt;/em&gt; within their field of study that sets them apart. Deliberate practice is not merely time spent working on the craft, but includes a &lt;a href=&#34;https://benmccormick.org/2018/08/02/feedback-loops/&#34;&gt;feedback loop&lt;/a&gt; aspect. To get better at something, we need to receive meaningful feedback on whether what we’re doing is working.&lt;/p&gt;
&lt;p&gt;When working with a team, one of the best ways to get this type of feedback is &lt;a href=&#34;https://benmccormick.org/2019/01/14/value-from-code-reviews&#34;&gt;quality code reviews&lt;/a&gt;. When you’re reviewing, you get to see other developers approaches to code, and when you’ve written code, you hopefully get high quality feedback from a different point of view.&lt;/p&gt;
&lt;p&gt;In reality, code reviews don’t always provide the value they could. Many developers don’t give much feedback at all on code reviews, give unhelpful aesthetic feedback, or may even use it abusively to try to show off their “superiority”. I can’t solve all of those problems, but here are a few tips I’ve found that help me get better feedback when my code is being reviewed.&lt;/p&gt;
&lt;h4 id=&#34;1.annotatepullrequests&#34;&gt;1. Annotate Pull Requests&lt;/h4&gt;
&lt;p&gt;Most people assume that the inline commenting features in Github and Bitbucket code reviews are for use by the people reviewing the code. But I’ve found that it can be helpful to preemptively add comments to my PRs to give reviewers context.
This is especially useful for information that may be relevant during a code review but isn’t long term relevant, like the original reason for extracting some reusable code and where it came from. Below is an example of a comment I left demoing how React hooks could be used to pull out shared logic in my work project.&lt;/p&gt;
&lt;figure&gt;&lt;br /&gt;
&lt;figcaption&gt;&lt;img style=&#34;display: block; margin-left: auto; margin-right: auto;&#34; title=&#34;comment-example.png&#34; src=&#34;https://benmccormick.micro.blog/uploads/2022/b6e42e48ed.png&#34; alt=&#34;Hooks comment example&#34; width=&#34;597&#34; height=&#34;192&#34; border=&#34;0&#34; /&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;These types of comments are also good ways to point a reviewer to the important parts of a review. This matters for reviews where there are many small changes across a large number of files, with a few high impact changes. It’s always better to make atomic changes (see &lt;a href=&#34;https://benmccormick.org/2019/01/14/value-from-code-reviews&#34;&gt;more here&lt;/a&gt;), but when you must make a large change, this technique can help a lot. I have received noticeably better feedback on my large pull requests since I began annotating&lt;/p&gt;
&lt;h4 id=&#34;2.encouragequestions&#34;&gt;2. Encourage Questions&lt;/h4&gt;
&lt;p&gt;If you’re receiving feedback from more junior members of a team, they may not always be comfortable giving direct feedback on code. One way to get better feedback in those situations is to encourage them to ask questions about things they don’t understand. This gives them opportunities to learn, but also let’s you see which parts of your code are unintuitive or unfamiliar to the rest of the team. In some cases the questions will expose bugs that a more confident reviewer may have pointed out straight out, and that experience can help grow a reviewers confidence and lead to even better feedback next time.&lt;/p&gt;
&lt;p&gt;Of course asking questions rather than assuming understanding can be a good tactic when giving feedback in general, and is worth considering when doing your own reviews regardless of whether a reviewer has encouraged it.&lt;/p&gt;
&lt;h4 id=&#34;3.findmorethanonereviewer&#34;&gt;3. Find More Than One Reviewer&lt;/h4&gt;
&lt;p&gt;This applies to more than just code, but if you’re not getting the feedback you need right now, ask somebody else. In a work setting, this might be finding different team members to review your code. If that isn’t possible at work, finding other ways to write code and get feedback on it can make a big difference in your career. Not everyone has time or capacity for this, but contributing to open source, project nights at local meetups and hackathons can all be great ways to learn and get feedback from others. If you can find a mentor to talk through code challenges with, that can be beneficial even if they aren’t on your team and going through your code line by line.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Ten Soft Skills That Will Shape Your Career</title>
      <link>https://benmccormick.org/2019/04/14/190000.html</link>
      <pubDate>Sun, 14 Apr 2019 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2019/04/15/190000.html</guid>
      <description>&lt;p&gt;One of the most popular posts in the history of my blog was a list with the click-baity name &lt;a href=&#34;https://benmccormick.org/2017/07/19/ten-things-javascript/&#34;&gt;Ten Things A Serious JavaScript Developer Should Learn&lt;/a&gt;.  It explicitly focused on the set of technical skills that you need to become a &amp;ldquo;senior&amp;rdquo; JavaScript developer.  While I&amp;rsquo;m happy with that post, I&amp;rsquo;ve always wanted to revisit the idea, because it is my strong belief that &lt;em&gt;once you&amp;rsquo;ve hit a minimum level of technical capability, only about 20% of career success is determined by your technical skills&lt;/em&gt;.  The other 80% is composed of skills that can be loosely bundled under &amp;ldquo;soft skills&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;You may quibble with my choice of percentage, but I don&amp;rsquo;t think the underlying idea that things other than technical ability is particularly controversial.  Even if they bitterly dismiss such things as &amp;ldquo;politics&amp;rdquo; most developers are aware that their careers are impacted by things that go beyond their ability to write algorithms.  What I haven&amp;rsquo;t seen much of however, are attempts to catalogue what these soft skills are, and how somebody might get better at them.  The second part is outside of the scope of a single post, though I will attempt to list resources here.  But the first is achievable, and that is what I will attempt to do here.&lt;/p&gt;
&lt;p&gt;The following is not an exhaustive list, but it covers 10 &amp;ldquo;soft skills&amp;rdquo; that I&amp;rsquo;ve seen have a clear impact on my career in software and those of others.  The best part? These are things you can grow in that will have an impact in your life outside of work, and in any career you might transition into in the future.&lt;/p&gt;
&lt;h3 id=&#34;the-skills&#34;&gt;The Skills&lt;/h3&gt;
&lt;h4 id=&#34;1-clear-communication&#34;&gt;1. Clear Communication&lt;/h4&gt;
&lt;p&gt;While I&amp;rsquo;m making bold statements: A developer&amp;rsquo;s ability to communicate clearly is the single most important skill in determining the trajectory of their career.  Poor communicators are forced to rely on others to interpret their work, even when it is brilliant.  They will often create problems for others through miscommunications or lead teams to make suboptimal decisions because they were not able to explain the technical considerations involved in a situation.&lt;/p&gt;
&lt;p&gt;Great communicators on the other hand, enlighten.  They help teams understand what is really going on so that non-technical team members can make good decisions, and technical folk can work with confidence.  Great communicators cut through misunderstandings, expose ambiguity and poor assumptions, and can translate for team members who are having trouble making themselves heard.&lt;/p&gt;
&lt;p&gt;Communication skills are important for those on a management track, but they are just as important for those on a technical trajectory. Architects, Principal Engineers and Tech Leads must coordinate with many teams, teach less experienced developers, explain technical tradeoffs and document decisions and code.  Those are core parts of a senior technical employee&amp;rsquo;s job, and all of them come down to communication.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Resources&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://benmccormick.org/2019/03/02/the-importance-of-writing&#34;&gt;The Importance Of Writing For Software Developers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.codingame.com/blog/10-tips-to-improve-your-communication-skills-as-a-software-developer/&#34;&gt;10 Tips to Improve your Communication Skills as a Software Developer&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;2-attention-management&#34;&gt;2. Attention Management&lt;/h4&gt;
&lt;p&gt;This one is more commonly referred to as &amp;ldquo;time management&amp;rdquo;, but I agree with &lt;a href=&#34;https://www.nytimes.com/2019/03/28/smarter-living/productivity-isnt-about-time-management-its-about-attention-management.html&#34;&gt;this recent NYT Op-Ed&lt;/a&gt;: the mechanics of how we organize our time is less important than whether we end up spending it on the most important things.  This broadly encompasses the ability to prioritize, to prevent distractions from wreaking havoc on productivity, and the ability to find ways to get back on track when things go wrong or priorities change.&lt;/p&gt;
&lt;p&gt;This was a weakness for me early in my career: I got things done but often did them haphazardly or inefficiently.  One of my biggest sources of growth in the last few years has been finding ways to structure and prioritize my time better, while cutting out distractions.  This has been necessary due to life changes: I&amp;rsquo;m now a parent and have people reporting to me at work.  I wouldn&amp;rsquo;t be able to meet my current responsibilities with the habits I had as a 25 year old.  For me this has been largely about focusing in on a small amount of essential things and actively removing less important things from my life.  For others it may be more about establishing patterns and limits.  Either way, this requires planning and introspection first to be effective.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Resources&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://amzn.to/2TqwDeR&#34;&gt;Deep Work - Cal Newport&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://bradfrost.com/blog/post/scheduling-every-minute-of-my-day/&#34;&gt;Scheduling Every Minute of My Day - Brad Frost&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.nytimes.com/2019/03/28/smarter-living/productivity-isnt-about-time-management-its-about-attention-management.html&#34;&gt;Productivity Isn&amp;rsquo;t About Time Management, It&amp;rsquo;s about Attention Management - Adam Grant&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;3-initiative&#34;&gt;3. Initiative&lt;/h4&gt;
&lt;p&gt;If you see an opportunity or a problem, do you do something about it?  I&amp;rsquo;ve been reading a good amount of &amp;ldquo;manager books&amp;rdquo; recently, and in many of them a surprising amount of focus is dedicated to the question of how we create conditions when people are &amp;ldquo;empowered&amp;rdquo; to act.  And there certainly is an environmental factor here.  People are more likely to take initiative and risks when they&amp;rsquo;re not afraid of being punished for it.  But the individual also controls a lot here.  Developers who are willing to step up and take initiative in a situation can make an outsize impact.&lt;/p&gt;
&lt;p&gt;Do you have a piece of code or process on your team that everybody acknowledges is a bit wonky, but nobody has ever taken the time to fix even though it is slowly taking a toll on the team over time?  Are there simple things that you know could make your product better, but nobody has quite taken the time to get to them?  Those are the opportunities that initiative can turn into value.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Resources&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://overreacted.io/fix-like-no-ones-watching/&#34;&gt;Fix Like No One&amp;rsquo;s Watching&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;4-empathy&#34;&gt;4. Empathy&lt;/h4&gt;
&lt;p&gt;There is no meaningful software product that has been created in isolation.  One person may have written the code (though that is quite rare for software with any scale of impact), and maybe even didn&amp;rsquo;t collaborate with anyone to handle distribution / hosting etc, but if that software is used by others there is always support, training and marketing to consider.  You can create a todo app for yourself without talking to anyone.  But nobody makes a career in this business without talking to other humans.&lt;/p&gt;
&lt;p&gt;The thing about us humans; we work well with people who we trust, and who we perceive as caring about us.  We also are for the most part exceptionally good at discerning when somebody is faking it.  So if we can&amp;rsquo;t get away from humans, and we can&amp;rsquo;t be fake, what can we do?  We are left with, in the words of Dale Carnegie &amp;ldquo;becoming genuinely interested in other people&amp;rdquo;.  If you&amp;rsquo;re currently filled with red-faced frustration at your annoying co-worker or manipulative boss, this may seem like asking for a miracle. And arguably any time we look outside ourselves it is a miracle. But regardless of your philosophical outlook on such things, there are definitely ways we can improve in how we work with and care for the people around us.  And it starts with trying to empathize and seeing the people around us as human beings and not obstacles or tools.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Resources&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://amzn.to/2Iiooe4&#34;&gt;How To Win Friends And Influence People - Dale Carnegie&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://amzn.to/2YSZasy&#34;&gt;Radical Candor - Kimball Scott&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://amzn.to/2WVkqfv&#34;&gt;I Hear You - Michael Sorenson&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;5-negotiation--persuasion&#34;&gt;5. Negotiation &amp;amp; Persuasion&lt;/h4&gt;
&lt;p&gt;You may not think that Software Engineering involves much negotiation.  But that is only true if you use a shallow definition of negotiation.  Every time a team debates implementation strategies for a feature, which tickets should end up in a sprint, and how much time to spend chasing a difficult to reproduce bug, they are engaging in negotiation, and team members are attempting to persuade.  And there is a wealth of knowledge out there describing how to improve on these skills.&lt;/p&gt;
&lt;p&gt;A word of caution here; unlike some of the other things on this list, these skills can often be dangerous when they&amp;rsquo;re improved in isolation.  When developers complain about politics trumping technical ability, they&amp;rsquo;re often experiencing decisions being made based on the ability of some employees to persuade and negotiate.  When those employees are not actually providing the best ideas this is suboptimal.  For the technically skilled employees, the answer is to learn to persuade better.  But for those who can negotiate we always need to make sure that we&amp;rsquo;re &lt;strong&gt;persuading for good&lt;/strong&gt;.  Just like the loudest voices shouldn&amp;rsquo;t always win, when you can communicate well, make sure to stay humble and  boost other&amp;rsquo;s good ideas when you see them.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Resources&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://amzn.to/2OUBnnl&#34;&gt;Negotiation Genius - Deepak Malhotra and Max Bazerman&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;6-continual-learning&#34;&gt;6. Continual Learning&lt;/h4&gt;
&lt;p&gt;Were you paying attention in high school physics when they taught about the difference between distance, velocity, and acceleration?  Distance is the amount an object has traveled.  Velocity is the speed at which it is currently moving in a given direction.  Acceleration is the rate at which the object&amp;rsquo;s velocity is changing.  If you want to know where an object is &lt;em&gt;right now&lt;/em&gt;, distance is the only thing that matters.  But as time progresses, velocity starts to matter more, and in the very long term any difference in acceleration will be the only thing that matters.&lt;/p&gt;
&lt;p&gt;The same ideas play out when acquiring skills.  If you need to evaluate your career potential for the next few months, the skills and accomplishments you&amp;rsquo;ve acquired so far (distance) are the only things that matter.  But if you want to think about your career potential over the next 30 years, the new skills you&amp;rsquo;re acquiring (velocity) and even more importantly your ability to get better at learning new things (acceleration) will matter much much more. Learning is a skill unto itself, and the earlier you invest in it the more dividends it will pay over time.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Resources&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://css-tricks.com/learning-to-learn/&#34;&gt;Learning To Learn - Sarah Drasner&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://benmccormick.org/2019/02/18/how-to-keep-learning-js&#34;&gt;How To Keep Learning JavaScript&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;7-self-care&#34;&gt;7. Self Care&lt;/h4&gt;
&lt;p&gt;Another lesson that I&amp;rsquo;ve learned the hard way in my career is the reality of my own mortality.  None of us are indestructible, and our bodies are not perpetual energy machines.  They require care and maintenance.  Our souls too are not meant to run on work alone, and we can burn out hard without sufficient rest.  This is all aside from deeper issues of disease and mental health that can change our lives in even more profound and difficult ways.&lt;/p&gt;
&lt;p&gt;Self care is a career skill because frankly we are great at deluding ourselves into thinking we&amp;rsquo;re functioning normally while we&amp;rsquo;ve compromised ourselves.  &lt;a href=&#34;https://www.thecut.com/2014/07/you-might-not-know-if-youre-sleep-deprived.html&#34;&gt;Research&lt;/a&gt; shows that we are horrible judges of whether our judgement and creativity are compromised by lack of sleep.  Because we can&amp;rsquo;t run controlled studies on ourselves, we don&amp;rsquo;t really know whether our lack of exercise or 60 hour workweek induced burnout are hurting our creativity.  But research suggests it is for pretty much everybody.&lt;/p&gt;
&lt;p&gt;Healthy socialization, sleeping, eating and exercise ultimately lead to better emotional stability, ability to focus, and creativity.  But even aside from the career benefits, when we&amp;rsquo;re devouring our bodies and minds for work, it leads to a question of what we&amp;rsquo;re doing this for in the first place.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Resources&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://amzn.to/2OVBpvx&#34;&gt;Why We Sleep - Matthew Walker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://benmccormick.org/2019/03/09/book-review-deep-work-common-rule&#34;&gt;Deep Work &amp;amp; The Common Rule&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;8-business-awareness&#34;&gt;8. Business Awareness&lt;/h4&gt;
&lt;p&gt;Do you know what your company actually does?  Do you understand why the features you&amp;rsquo;re building are important, and the relative priority of them?  Can you explain the business tradeoffs involved when you&amp;rsquo;re making an software architecture decision between performance and security?&lt;/p&gt;
&lt;p&gt;In companies larger than a few people it&amp;rsquo;s not ultimately developers&#39; jobs to make business decisions.  But understanding the context for those decisions helps us better prioritize our time, make good tradeoffs, and call attention to inefficiencies or counterproductive behavior in our products. In addition, nobody wants to spend time working on things that don&amp;rsquo;t matter. But when we try to innovate without understanding the broader business, we often end up doing just that.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Resources&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://mcfunley.com/choose-boring-technology&#34;&gt;Choose Boring Technology - Dan McKinley&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;9-marketing-and-branding&#34;&gt;9. Marketing and Branding&lt;/h4&gt;
&lt;p&gt;Marketing is a dirty word in engineering circles.  Many take the attitude of the Dilbert comics that &lt;a href=&#34;https://dilbert.com/strip/1997-05-02&#34;&gt;marketing is a synonym for exaggeration lying, and fraud&lt;/a&gt;.  But at it&amp;rsquo;s core marketing is just making sure that the people who could benefit from your services are aware of those services.  This has several applications to developers.  In the job market, finding ways to let employers know who you are and what you&amp;rsquo;re capable of is important.  But in medium to large companies it also is important to do some level of internal marketing; to make sure you&amp;rsquo;re credited for the work you&amp;rsquo;ve done and that people understand it&amp;rsquo;s values.  Developers who consider themselves above this or dismiss it as politics do so at their own peril.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Resources&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.stephaniemorillo.co/single-post/2019/02/17/7-Common-Content-Marketing-Mistakes-Developers-Make-and-How-to-Avoid-Them&#34;&gt;7 Common Content Marketing Mistakes Developers Make and How to Avoid Them - Stephanie Morillo&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;10-character&#34;&gt;10. Character&lt;/h4&gt;
&lt;p&gt;The final item here is in some ways an oddball.  While the other 9 things on this list are skills that you can work on, character is something deeper.  Questions of what good character is and how you develop it are way outside the scope of this post.  And I would personally consider any attempt to improve your character for solely utilitarian career reasons to be ultimately hollow.  But character is undeniably important in your career.&lt;/p&gt;
&lt;p&gt;Do the people around you trust you?  Do they believe that you&amp;rsquo;re trying to do the right thing?  If the answers are no, you may find obstacles in the most unexpected places.  If the answers are yes, you will eventually find help from people you would never have looked to.&lt;/p&gt;
&lt;p&gt;In addition, as an industry, technology has the power to shape the world, and as practitioners we all get the chance to impact our little corners of the world.  It&amp;rsquo;s worth considering not just whether we&amp;rsquo;re &amp;ldquo;succeeding in our career&amp;rdquo;, but what impact we&amp;rsquo;re having on the world around us.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Resources&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://amzn.to/2I5jP7K&#34;&gt;Future Ethics - Cennydd Bowles&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Consistency</title>
      <link>https://benmccormick.org/2019/03/31/190000.html</link>
      <pubDate>Sun, 31 Mar 2019 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2019/04/01/190000.html</guid>
      <description>&lt;p&gt;The last few weeks I&amp;rsquo;ve had several conversations with a coworker about consistency in code: why do we do things one way here, and a different way there?  Some of this is macro level; Where do we split chunks of related functionality into different files?  Some of it is micro level; what should the rules be for when we use an inline function instead of pulling it out into its own named method?  Some of it is trivial; Do we use &lt;code&gt;_&lt;/code&gt; or &lt;code&gt;-&lt;/code&gt; to separate words in file names?  In our current codebase we&amp;rsquo;re not always consistent on many of these issues.  As we&amp;rsquo;ve discussed the various issues, I realized that some of them bothered me more than others, and (more interestingly to me) my ideas have changed here over time.&lt;/p&gt;
&lt;h3 id=&#34;the-platonic-ideal&#34;&gt;The Platonic Ideal&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;In a perfectly consistent system, 3 developers writing the same module would produce line by line identical code&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;There&amp;rsquo;s an extreme point of view out there that says &amp;ldquo;while a perfectly consistent system might not be possible, the closer we can get to that the better&amp;rdquo;.  The benefits of consistency are many: consistent naming helps with code search and connecting different parts of a system.  Consistent code structure makes code easier to scan once a developer is familiar with the system, and it makes exceptions stand out as something intentional and interesting.  Consistent formatting removes potential distractions.   So what&amp;rsquo;s not to love?  Shouldn&amp;rsquo;t we always try to add more consistency?  I see 2 primary reasons why it might not be worth trying to enforce every single rule we can come up with.&lt;/p&gt;
&lt;h4 id=&#34;were-only-human&#34;&gt;We&amp;rsquo;re only human&lt;/h4&gt;
&lt;p&gt;The first reason not to enforce &amp;ldquo;everything&amp;rdquo; is that our human attention spans can only internalize so many rules at once.  When we&amp;rsquo;re trying to remember a large number of rules, its easy to miss one.  But more importantly, when we&amp;rsquo;re writing code or reviewing it, focusing too much on human enforced consistency rules can distract from the actual purpose of the code, making it harder to notice the substance of code because we&amp;rsquo;re so focused on the form.&lt;/p&gt;
&lt;h4 id=&#34;standards-too-soon&#34;&gt;Standards too soon&lt;/h4&gt;
&lt;p&gt;The other thing that can happen when you try to standardize everything is a loss of creativity.  Sometimes it&amp;rsquo;s helpful to experiment for a while to find the right pattern in a codebase.  In an ideal situation experiments like that will happen on the side, or be explored in branches, but for small teams or new codebases, it will likely happen at least partially in production.&lt;/p&gt;
&lt;h3 id=&#34;user-friendly-consistency&#34;&gt;User Friendly Consistency&lt;/h3&gt;
&lt;p&gt;So what &lt;strong&gt;can&lt;/strong&gt; we do to get the benefits of consistency? The 4 ways I like to see this happen are:&lt;/p&gt;
&lt;h4 id=&#34;automation&#34;&gt;Automation&lt;/h4&gt;
&lt;p&gt;The best way to enforce stylistic consistency and other straightforward things like naming conventions is to use automation.  Linters like &lt;a href=&#34;https://eslint.org/&#34;&gt;eslint&lt;/a&gt; and auto-formatters like &lt;a href=&#34;https://prettier.io/&#34;&gt;Prettier&lt;/a&gt;.  My rule here is that any linter rule that is about stylistic consistency should be auto-fixable, if not it isn&amp;rsquo;t clear enough or isn&amp;rsquo;t worth it.  For &amp;ldquo;correctness rules&amp;rdquo; it can be ok to flag errors without auto-fixing, if human judgement is needed.&lt;/p&gt;
&lt;h4 id=&#34;code-review-checklists&#34;&gt;Code Review Checklists&lt;/h4&gt;
&lt;p&gt;Code reviews can be a good way to limitedly enforce consistency; but its good to limit scope to avoid &lt;a href=&#34;https://samsaccone.com/posts/code-reviews-not-nits.html&#34;&gt;developers trying to become human compilers&lt;/a&gt;.  If you try to enforce too many things in code reviews, its easy for people to get caught up in going through a list and forget to apply human judgement to the context of the current code. But &lt;a href=&#34;https://benmccormick.org/2019/01/14/value-from-code-reviews&#34;&gt;code review checklists&lt;/a&gt; are a good way to make a coordinated push on high value items that are either new or often neglected.  This checklist should consist of a few important things to check during every review. The list should be re-examined on a regular basis and ideally kept to 5 or less items.&lt;/p&gt;
&lt;h4 id=&#34;focused-refactoring&#34;&gt;Focused Refactoring&lt;/h4&gt;
&lt;p&gt;Sometimes its appropriate to have &amp;ldquo;refactoring initiatives&amp;rdquo; to standardize on a particular pattern over time.  This can be good for standardizing on a particular library for a task, or removing an older pattern that persists in the codebase after a better way has been found.  My advice here is to &lt;a href=&#34;https://benmccormick.org/2018/01/07/large-improvements-small-team/&#34;&gt;only do one of these at a time, and complete them before starting a new one&lt;/a&gt;.  One of the biggest causes of inconsistency is when a team attempts to &amp;ldquo;&lt;a href=&#34;https://xkcd.com/927/&#34;&gt;standardize&lt;/a&gt;&amp;rdquo; on a solution, then abandons that for a new solution without finish the migration, resulting in a &lt;a href=&#34;http://mikehadlow.blogspot.com/2014/12/the-lava-layer-anti-pattern.html&#34;&gt;lava layer architecture&lt;/a&gt;.&lt;/p&gt;
&lt;h4 id=&#34;focus-on-the-high-level&#34;&gt;Focus on the high level&lt;/h4&gt;
&lt;p&gt;If there is one place to apply human consistency checks its at the structural level.  If your high level patterns are consistent, the code base will be easy to navigate, and modular code written in a standardized high level structure will be &lt;a href=&#34;https://programmingisterrible.com/post/139222674273/write-code-that-is-easy-to-delete-not-easy-to&#34;&gt;easy to delete&lt;/a&gt;.  Overall low level code that is inconsistent or poorly written is easier to overcome than high level code as long as you&amp;rsquo;re taking advantage of code reviews and the other methods suggested here to improve new code, because most low level code is only read occasionally.  So high traffic &amp;ldquo;messy code&amp;rdquo; can be a focus of refactoring efforts, and the rest can continue working without disturbing anything.&lt;/p&gt;
&lt;p&gt;Messy code is much more problematic at a structural level though, because when different areas of the code are arranged in different ways, it becomes much harder to find functionality when debugging.  This type of inconsistency also tends to make bulk improvements harder, as you have to have a much greater understanding of all the ways a codebase is put together.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Lessons from Six Months As A Manager/Developer Hybrid</title>
      <link>https://benmccormick.org/2019/03/24/190000.html</link>
      <pubDate>Sun, 24 Mar 2019 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2019/03/25/190000.html</guid>
      <description>&lt;p&gt;For the last 6 months I&amp;rsquo;ve been serving as a hybrid developer/engineering manager.  It&amp;rsquo;s been an interesting experience, and because this is a fairly common way to transition into engineering management&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;, I thought it might be worthwhile to share some lessons I&amp;rsquo;ve learned so far.&lt;/p&gt;
&lt;h4 id=&#34;1-time-discipline-is-key&#34;&gt;1. Time discipline is key&lt;/h4&gt;
&lt;p&gt;The biggest challenge of this transition was learning to be a manager.  It&amp;rsquo;s a whole new job!  But the biggest challenge specific to the management/developer split has been managing my time.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve always been a bit loose with my time management.  I do a lot based on my mental state at a particular time; if I&amp;rsquo;m tired or uninspired I may lean more into grunt work like documentation, code reviews, or more &amp;ldquo;scripted&amp;rdquo; code work.  If I&amp;rsquo;m in the zone I&amp;rsquo;ll dive into big tasks, and if someone comes to me with a problem I tend to context shift into it and go from there.&lt;/p&gt;
&lt;p&gt;This &amp;ldquo;time management strategy&amp;rdquo; hasn&amp;rsquo;t held up at all while trying to balance manager and development strategies.  Basically because of the blend of &lt;a href=&#34;http://www.paulgraham.com/makersschedule.html&#34;&gt;maker and manager schedules&lt;/a&gt;.  Developers need long uninterrupted periods of time to be productive, while managers tend to operate on a much more social and interrupt driven schedule.  They&amp;rsquo;re naturally opposed.&lt;/p&gt;
&lt;p&gt;Working with this tension requires discipline and planning.  For me personally I&amp;rsquo;ve started planning my schedule for the next day at the end of the previous day, batching my checking of Slack/email and being more thoughtful when somebody asks for my time.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Planning my schedule for the next day&lt;/strong&gt; is a tip I picked up from &lt;a href=&#34;https://benmccormick.org/2019/03/09/book-review-deep-work-common-rule&#34;&gt;Deep Work&lt;/a&gt;.  To close out the day, I review the things I&amp;rsquo;ll need to handle the next day, and block out my calendar with time for different tasks for the next day.  This does mean that my calendar &lt;em&gt;always looks completely booked for the current day&lt;/em&gt;.  So far this has served as a feature not a bug; I can still move things if something urgent comes up and it has a way of encouraging people to schedule less urgent things in advance.  Note that scheduling like this doesn&amp;rsquo;t mean you can&amp;rsquo;t change plans; I do all the time.  It just means that you start with a plan and can be thoughtful about how you vary off of it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Batching Slack and email&lt;/strong&gt; has been something I&amp;rsquo;ve known would be good for me forever.  It feels good in the moment to be the guy who is constantly available, but the cost of distraction is higher than you think.  So far, management has been a catalyst for me buckling down here.&lt;/p&gt;
&lt;p&gt;Finally, I get a lot more unexpected requests for my time now than I did previously.  I&amp;rsquo;ve found that batching my email and Slack reading combined with &lt;strong&gt;a willingness to suggest a meeting later in the day or the next morning rather than &lt;em&gt;right now&lt;/em&gt;&lt;/strong&gt; has helped me protect blocks of productivity and focus, without making me an unresponsive manager.  Most things can sit for 2 hours without blowing up anyone&amp;rsquo;s day.  The key is to ask enough to identify the 5% of things that can&amp;rsquo;t wait.&lt;/p&gt;
&lt;p&gt;Those 3 tactics have worked for me, but overall it comes down to being intentional about your time.  If you let yourself be blown by the wind while splitting dual responsibilities, one of them will almost always receive the short end of the stick.&lt;/p&gt;
&lt;h4 id=&#34;2-team-success-metrics-are-the-only-ones-that-matter&#34;&gt;2. Team success metrics are the only ones that matter&lt;/h4&gt;
&lt;p&gt;When you&amp;rsquo;re acting as both a developer and a manager, it can be tempting to hold yourselves to 2 sets of metrics: management metrics and development metrics.  This is a mistake.  It will cause you to over-prioritize your own tasks and hurt your team&amp;rsquo;s long term growth.&lt;/p&gt;
&lt;p&gt;Focusing on personal development metrics and goals can lead to over-prioritizing them for a few reasons. First, development goals tend to be much &amp;ldquo;cleaner&amp;rdquo; than management goals; it&amp;rsquo;s easier to tell what you&amp;rsquo;ve achieved.  Second, if you&amp;rsquo;re transitioning into this role from a dev role, you probably are much more comfortable with these tasks, and so they can act as a safe place where you avoid having to stretch yourself.  And finally, if you moved into this role from a senior dev position, it can be easy to tell yourself that this is actually the best way to get stuff done.  And you may be right&amp;hellip; in the short term.&lt;/p&gt;
&lt;p&gt;So what&amp;rsquo;s the antidote?  Focus on team productivity and view your own work as just an extra card you have to play in your hand.  It&amp;rsquo;s an advantage you have over less technical managers, but if you don&amp;rsquo;t set to working developing other strengths, you&amp;rsquo;re not going to be able to grow, and if you&amp;rsquo;re monopolizing the important work your team won&amp;rsquo;t be able to step up into new roles.  So play that card, but do it with caution, and always as a means rather than an end.&lt;/p&gt;
&lt;h4 id=&#34;3-this-isnt-long-term-sustainable-have-a-plan&#34;&gt;3. This isn’t long term sustainable; have a plan&lt;/h4&gt;
&lt;p&gt;Hybrid Management / Developer roles aren&amp;rsquo;t a long term game.  Aside from the scheduling tension I mentioned above, once you move into this role you&amp;rsquo;re either going to be slowly giving up responsibilities and watching your tech skills slowly move off the cutting edge as you focus on learning how to manager your team and developing others to fill the roles you once did, or you&amp;rsquo;re going to be failing as a manager as you try to cling too tightly to your senior individual contributor responsibilities.  So if you want to avoid that, it&amp;rsquo;s important to be evaluating how you want your career to evolve.  A role like this can be a first step up a chain, or part of a &lt;a href=&#34;https://charity.wtf/2017/05/11/the-engineer-manager-pendulum/&#34;&gt;dev to manager pendulum&lt;/a&gt;.  You also might discover that management isn&amp;rsquo;t for you and decide to move back.  I&amp;rsquo;m committed to this for a set period of time, and that&amp;rsquo;s helped me to work through the days when I wonder what I actually accomplished, and think strategically about what I need to get better at.&lt;/p&gt;
&lt;h4 id=&#34;4-best-management-resources&#34;&gt;4. Best Management resources&lt;/h4&gt;
&lt;p&gt;So this isn&amp;rsquo;t a learning so much, but as a newbie manager, probably the best thing I can do is point you to the resources I&amp;rsquo;ve found helpful.  So here are some of the best.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;On Engineering Management&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://randsinrepose.com/&#34;&gt;Rands In Repose&lt;/a&gt; by Michael Lopp and &lt;a href=&#34;https://amzn.to/2Clyjvy&#34;&gt;the book he pulled out of the blog&lt;/a&gt; are great little snippets of engineering management gold&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://us2.campaign-archive.com/home/?u=1f50ce22f02ed0ffc80c10aff&amp;amp;id=8c0f947e69&#34;&gt;Lara Hogan&amp;rsquo;s Newsletter&lt;/a&gt; is full of useful advice, and she&amp;rsquo;s really good about including exercises to help practice what she&amp;rsquo;s describing.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;On Management Generally&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://amzn.to/2F4i0ni&#34;&gt;Radical Candor&lt;/a&gt; is the single most helpful thing I&amp;rsquo;ve read while trying to figure out this whole management thing&lt;/li&gt;
&lt;li&gt;Patrick Lencioni&amp;rsquo;s books are all told as &amp;ldquo;leadership fables&amp;rdquo; which can seem a bit weird, but in the squishy imprecise world of management, stories can be very effective ways to teach.  I&amp;rsquo;ve read &lt;a href=&#34;https://amzn.to/2UCPpvT&#34;&gt;The Five Dysfunctions of a Team&lt;/a&gt;, &lt;a href=&#34;https://amzn.to/2UIaxkr&#34;&gt;Death By Meeting&lt;/a&gt; and &lt;a href=&#34;https://amzn.to/2CqYalR&#34;&gt;Silos, Politics, and Turf Wars&lt;/a&gt;.  They&amp;rsquo;ve all been great and I plan to read more of his stuff.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;On Structuring My Time&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I reviewed it last week, but &lt;a href=&#34;https://amzn.to/2UBcIGy&#34;&gt;Deep Work&lt;/a&gt; was super helpful in thinking through how to balance my time.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;On Career Path&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I linked this one above, but if you didn&amp;rsquo;t click through then Charity Major&amp;rsquo;s post on the &lt;a href=&#34;https://charity.wtf/2017/05/11/the-engineer-manager-pendulum/&#34;&gt;Engineer/Manager Pendulum&lt;/a&gt; has been really helpful for pushing me to think through where I want to go next.&lt;/li&gt;
&lt;/ul&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;I&amp;rsquo;m aware that lots of folks would say that this is a very &lt;em&gt;bad&lt;/em&gt; way to start management and that you should stop coding when you become a manager, but it isn&amp;rsquo;t always possible to fully control what opportunities are available.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>Utility Functions</title>
      <link>https://benmccormick.org/2019/03/10/190000.html</link>
      <pubDate>Sun, 10 Mar 2019 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2019/03/11/190000.html</guid>
      <description>&lt;p&gt;As I&amp;rsquo;ve gone through projects over time, I&amp;rsquo;ve found a few functions that I end up creating for every significant project that I&amp;rsquo;ve worked on.  Some of the details differ from project to project, but the basic function remains the same.  I thought it would be helpful to do a rundown:&lt;/p&gt;
&lt;h3 id=&#34;reactjsx&#34;&gt;React/JSX&lt;/h3&gt;
&lt;p&gt;Some of my utils are focused on making JSX nicer to deal with.  2 situations that I&amp;rsquo;ve run into a lot in JSX are conditionally showing an item in JSX, and determining which of several classes to add to an element based on logic.  Scenarios like these:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;div&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;
    {shouldShowCreateButton &lt;span style=&#34;color:#ff79c6&#34;&gt;?&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;Button
            onClick&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;{createWidget}
            type &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;primary&amp;#39;&lt;/span&gt;
            size &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Large&amp;#39;&lt;/span&gt;
            disabled &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {&lt;span style=&#34;color:#ff79c6&#34;&gt;!&lt;/span&gt;createEnabled}
            className&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;create-button&amp;#39;&lt;/span&gt;
        &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;
            Create Widget
        &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;/Button&amp;gt; : null}
&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; classNames &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;create-button&amp;#39;&lt;/span&gt;
&lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (extraClass) {
    classNames &lt;span style=&#34;color:#ff79c6&#34;&gt;+=&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39; &amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; extraClass;
}
&lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (createEnabled) {
    classNames &lt;span style=&#34;color:#ff79c6&#34;&gt;+=&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39; is-disabled&amp;#39;&lt;/span&gt;);
}
&lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (hasCreateError) {
    classNames &lt;span style=&#34;color:#ff79c6&#34;&gt;+=&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39; has-error&amp;#39;&lt;/span&gt;;
}
&lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;Button
        onClick&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;{createWidget}
        type &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;primary&amp;#39;&lt;/span&gt;
        size &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Large&amp;#39;&lt;/span&gt;
        disabled &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {&lt;span style=&#34;color:#ff79c6&#34;&gt;!&lt;/span&gt;createEnabled}
        className&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;{classNames}
    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;
        Create Widget
&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;/Button&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;These are both ok, and you&amp;rsquo;ll see plenty of examples of code like them out there, but the first puts a big chunk of code in a ternary, and it&amp;rsquo;s not always going to be clear to a reader where that &lt;code&gt;: null&lt;/code&gt; came from at the end, or why it&amp;rsquo;s there by the time they reach the end.&lt;/p&gt;
&lt;p&gt;In the second example, we&amp;rsquo;re dealing with a lot of ugly string concatenation.  There are other ways to handle this, like using template strings + ternaries but generally they each provide their own messy pieces.&lt;/p&gt;
&lt;p&gt;To solve these situations, I like to define these 2 small functions:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; isString from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;lodash-es/isString&amp;#39;&lt;/span&gt;;
&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; filter from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;lodash-es/filter&amp;#39;&lt;/span&gt;;
&lt;span style=&#34;color:#6272a4&#34;&gt;// A helper for React Components to reduce ternary use
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; showIf &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; (condition, element) =&amp;gt; (condition &lt;span style=&#34;color:#ff79c6&#34;&gt;?&lt;/span&gt; element &lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;null&lt;/span&gt;);

&lt;span style=&#34;color:#6272a4&#34;&gt;// A helper for handling class lists where some values may be undefined
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;// filters out anything that isn&amp;#39;t a string and then adds spaces
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; classes &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; classList =&amp;gt; {
    &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; filter(classList, c =&amp;gt; {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; isString(c) &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; c.length &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;0&lt;/span&gt;;
    }).join(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39; &amp;#39;&lt;/span&gt;);
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The first just formalizes the most common use of ternaries in JSX (conditionally showing an item) and adds an easy to understand name to it.&lt;/p&gt;
&lt;p&gt;The second lets us work with an array of classNames instead of handling string concat ourselves, and will automatically filter out undefined or empty classNames.  This implementation does silently swallow errors on anything that is not a string, which may not be your preference.  Usage looks like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;div&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;
    {showIf(shouldShowCreateButton, &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;Button
            onClick&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;{createWidget}
            type &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;primary&amp;#39;&lt;/span&gt;
            size &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Large&amp;#39;&lt;/span&gt;
            disabled &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {&lt;span style=&#34;color:#ff79c6&#34;&gt;!&lt;/span&gt;createEnabled}
            className&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;create-button&amp;#39;&lt;/span&gt;
        &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;
            Create Widget
        &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;/Button&amp;gt;)}
&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;the showIf reads much more clearly than the previous ternary, especially for language newbies who might not be used to ternaries.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; classNames &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; [&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;create-button&amp;#39;&lt;/span&gt;, extraClass];
&lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (createEnabled) {
    classNames.push(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;is-disabled&amp;#39;&lt;/span&gt;);
}
&lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (hasCreateError) {
    classNames.push(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;has-error&amp;#39;&lt;/span&gt;);
}
&lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;Button
        onClick&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;{createWidget}
        type &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;primary&amp;#39;&lt;/span&gt;
        size &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Large&amp;#39;&lt;/span&gt;
        disabled &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {&lt;span style=&#34;color:#ff79c6&#34;&gt;!&lt;/span&gt;createEnabled}
        className&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;{classes(classNames)}
    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;
        Create Widget
&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;/Button&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Here we&amp;rsquo;ve gotten rid of the extra string code and are working on arrays, which is a nicer data structure for dealing with lists of stuff. Also since we&amp;rsquo;re auto-filtering falsy stuff, we don&amp;rsquo;t have to worry about whether extraClass was defined if it was passed as a prop to our component or something.&lt;/p&gt;
&lt;h3 id=&#34;formatting&#34;&gt;Formatting&lt;/h3&gt;
&lt;p&gt;So the next few may be different for everyone.  The details here aren&amp;rsquo;t important, the important thing is that you centralize your formatting of numbers and dates.  For instance, here are functions for formatting dates, normal numbers and percentages from a current project:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; { format } from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;date-fns&amp;#39;&lt;/span&gt;;
&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; isNumber from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;lodash-es/isNumber&amp;#39;&lt;/span&gt;;

&lt;span style=&#34;color:#6272a4&#34;&gt;// takes either a string or a date object and formats it as a standard date with time
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; stdFormat &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; dateStr =&amp;gt; {
    &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#ff79c6&#34;&gt;!&lt;/span&gt;dateStr) {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; dateStr;
    }
    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; date &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;Date&lt;/span&gt;(dateStr);
    &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; format(date, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;MM/DD/YY hh:mm A&amp;#39;&lt;/span&gt;);
};

&lt;span style=&#34;color:#ff79c6&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; commafy &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; (num, minDecimals &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;0&lt;/span&gt;) =&amp;gt; {
    &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (isNumber(num)) {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; num.toLocaleString(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;en-US&amp;#39;&lt;/span&gt;, {
            minimumFractionDigits&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; minDecimals,
        });
    } &lt;span style=&#34;color:#ff79c6&#34;&gt;else&lt;/span&gt; {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; num;
    }
};

&lt;span style=&#34;color:#ff79c6&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; percentify &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; (num, minDecimals &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;0&lt;/span&gt;) =&amp;gt; {
    &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (isNumber(num)) {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; num.toLocaleString(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;en-US&amp;#39;&lt;/span&gt;, {
            style&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;percent&amp;#39;&lt;/span&gt;,
            minimumFractionDigits&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; minDecimals,
        });
    } &lt;span style=&#34;color:#ff79c6&#34;&gt;else&lt;/span&gt; {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; num;
    }
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The first one will take a date object and format it to something like &lt;code&gt;05/30/17 01:16 PM&lt;/code&gt;.  The second will take a number and return a string formatted with appropriate commas: &lt;code&gt;1234567 -&amp;gt; &#39;1,234,567&#39;&lt;/code&gt;.  The last one will convert a decimal to a percentage string: &lt;code&gt;0.5 -&amp;gt; &#39;50%&#39;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Note that none of these functions are very long.  I&amp;rsquo;m relying on a date library for the first piece and &lt;code&gt;toLocaleString&lt;/code&gt; for the other 2.  So I could inline this in most places and not have it get much longer.  The benefit of these types of functions is not in saving typing.  It&amp;rsquo;s in standardizing how you format or don&amp;rsquo;t format things throughout an application.  This has 2 benefits:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;It&amp;rsquo;s easy to fix bugs, add features or switch between libraries for these common tasks across your application because all of the logic is centralized.  If I needed to start supporting more locales than just the US for percentage formatting, or use moment for my date formatting library I could easily do so with edits to only one file.  That file is also well unit tested, so those transitions would be safe.&lt;/li&gt;
&lt;li&gt;It lets us control which formats are allowed.  For instance we&amp;rsquo;re allowing the function caller to specify how many decimal points to show for the numeric functions, but not giving options to change the date format for the formatting function, because we want that to be the same everywhere.  If we need to support multiple formats for different scenarios, like a date-only format or a format for communicating with the API, we can add options for that which don&amp;rsquo;t open up all formats, or expose them as separate functions.  With dates in particular, I want imports of libraries like moment or date-fns to be limited to 2 or 3 files at the most, and not used ad-hoc throughout the codebase.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Note that all my examples so far have utilized other utility libraries like lodash and date-fns.  The best utility functions are those that you don&amp;rsquo;t have to maintain yourself.  I do recommend looking for libraries that you can tree-shake and only take what you need though.  Other ones like moment.js can make a big difference on your JavaScript bundle size if you let them.&lt;/p&gt;
&lt;h3 id=&#34;timing&#34;&gt;Timing&lt;/h3&gt;
&lt;p&gt;Timeout functions are useful, but the browsers built in functions are callback based and don&amp;rsquo;t play well with promises or async await.  We can fix that:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; sleep &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; secs =&amp;gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;Promise&lt;/span&gt;(res =&amp;gt; setTimeout(res, secs &lt;span style=&#34;color:#ff79c6&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1000&lt;/span&gt;));
&lt;span style=&#34;color:#ff79c6&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; pause &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; () =&amp;gt; sleep(&lt;span style=&#34;color:#bd93f9&#34;&gt;0&lt;/span&gt;);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I now have a promisified version of setTimeout (&lt;code&gt;sleep&lt;/code&gt;) and a special case version with a 0 timeout (useful for things that should happen as soon as possible after the current event loop executes. I prefer dealing with things in seconds over milliseconds, so I changed the API to use that.  That is probably not everyone&amp;rsquo;s cup of tea, so feel free to copy and modify.&lt;/p&gt;
&lt;p&gt;Usage looks like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;// function to kick off a &amp;#34;job&amp;#34; of some type and then
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;// check every 30 seconds to see if the job is complete
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; createJobAndShowResults &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;async&lt;/span&gt; () =&amp;gt; {
    createJob();
    &lt;span style=&#34;color:#6272a4&#34;&gt;// don&amp;#39;t do this without a timeout/failure
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#6272a4&#34;&gt;// condition in real life!
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#ff79c6&#34;&gt;while&lt;/span&gt;(&lt;span style=&#34;color:#ff79c6&#34;&gt;true&lt;/span&gt;) {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;await&lt;/span&gt; sleep(&lt;span style=&#34;color:#bd93f9&#34;&gt;30&lt;/span&gt;);
        &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; jobStatus &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; checkIfJobIsCompleted();
        &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (jobStatus.complete) {
            &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; jobStatus;
        }
    }
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;and-even-more&#34;&gt;And Even More!&lt;/h3&gt;
&lt;p&gt;This is just a sample of the small functions I usually create in projects.  Pretty much all of them exist for one or more of the reasons that were already discussed:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Smoothing over awkward library syntax like multiple classes in JSX or HTML templates&lt;/li&gt;
&lt;li&gt;Making user intention clear with a well named function, like showIf or stdDateFormat&lt;/li&gt;
&lt;li&gt;Ensuring consistent application-specific behavior across common low-level operations like formatting or logging&lt;/li&gt;
&lt;li&gt;Making it easy to replace 3rd party utility libraries  like date-fns by wrapping them in an application specific function&lt;/li&gt;
&lt;li&gt;Improving browser level APIs, or shaping them to have useful defaults for the current application, like we did with toLocaleString and setTimeout.&lt;/li&gt;
&lt;/ol&gt;
</description>
    </item>
    
    <item>
      <title>Book Review: Deep Work &amp; The Common Rule</title>
      <link>https://benmccormick.org/2019/03/08/190000.html</link>
      <pubDate>Fri, 08 Mar 2019 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2019/03/09/190000.html</guid>
      <description>&lt;p&gt;I&amp;rsquo;m trying something different today.  This is a review of 2 books I&amp;rsquo;ve read recently; I&amp;rsquo;m combining them because their similarities and differences are just as interesting to me as the practical steps they encourage.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://amzn.to/2TqwDeR&#34;&gt;Deep Work&lt;/a&gt; is a 3 year old book from Cal Newport focused on encouraging readers to spend more time on their most important work.  It starts out with sections defining and motivating &amp;ldquo;Deep Work&amp;rdquo;: focusing without distraction on cognitively demanding tasks.  Then it goes on to give a series of recommended strategies for creating more and better deep work time in your life.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://amzn.to/2F0AIgV&#34;&gt;The Common Rule&lt;/a&gt; is a new book by Justin Earley focused on building habits that allow living life with purpose.  It is a &amp;ldquo;Christian book&amp;rdquo;, and recommends practices like daily prayer and fasting.  But it is mainly focused on encouraging habits to combat some universal challenges of modern American life: distracting technologies, all consuming work environments, and increasing isolation.&lt;/p&gt;
&lt;h3 id=&#34;a-shared-diagnosis&#34;&gt;A Shared Diagnosis&lt;/h3&gt;
&lt;p&gt;Deep Work and The Common Rule share a common view on the challenges facing many American adults today: they each tackle tech distractions, work expectations of constant availability, and time spent on shallow activities disconnected from our core goals and desires.&lt;/p&gt;
&lt;p&gt;Both authors are skeptical of modern &amp;ldquo;networking tools&amp;rdquo; like social networks, chat tools, news sites and email without dismissing them.  The primary issue both authors identify as the problem with technology is our non-critical acceptance of new tools into our lives as progress, the addictive nature of these services, and how they then impact our brains. Because we turn to technology for distraction and easy comfort whenever we&amp;rsquo;re bored, we lose our capacity for deeper engagement with the world and can lose sight of more important things.&lt;/p&gt;
&lt;p&gt;Each book also decries the problems with &amp;ldquo;constant connectivity culture&amp;rdquo;.  Deep Work comes at it from a pure productivity standpoint: expectations of constant availability create distractions that prevent us from getting into the flow of meaningful work, and when we&amp;rsquo;re answering emails at all hours of the day, we don&amp;rsquo;t get the context shifts where our brains can rest and help us be more productive later.  The Common Rule shares these concerns but is more interested in how these distractions can shape our thinking and emotions: when we get sucked into the world of social media news for instance, is the anger we feel about issues a reflection of our true priorities or a path that we&amp;rsquo;ve fallen down.  It also asks us to consider how long term media-consumption may shape these believes and not just distract from them.&lt;/p&gt;
&lt;p&gt;Finally, both authors touch on the amount of time we spend on meaningless activities.  Whether it is busy work, meetings, social media usage we feel we &amp;ldquo;have to do&amp;rdquo; or &amp;ldquo;real work&amp;rdquo; that just isn&amp;rsquo;t the most important work, both books encourage readers to value their time and be strategic about how to spend it.  They share a rare humble view of the human condition: we really do need to work with only 24 hours a day.  How to &amp;ldquo;make the most of them&amp;rdquo; is a core focus of each book.&lt;/p&gt;
&lt;h3 id=&#34;a-suprisingly-similar-recommendation&#34;&gt;A Suprisingly Similar Recommendation&lt;/h3&gt;
&lt;p&gt;In addition to a shared view of the problems people face, both books share a fairly similar approach to solving them.  Both books recommend ritualized structuring of life to reduce time spent on shallow, distracting activities and enable time for &amp;ldquo;the good life&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;So&amp;hellip; what is &amp;ldquo;ritualized structuring&amp;rdquo;?  Both books spend significant time outlying a series of recommended habits/rituals that combine to help make us more aware of how our time is spent, and also serve as enabling spaces for &amp;ldquo;the good life&amp;rdquo;.  Deep work recommends (among other things) structured work hours, work-free evenings, social media avoidance and end of the day &amp;ldquo;shutdown rituals&amp;rdquo; where you clean up todos and make a schedule for the next day.  The Common Rule advocates for taking an hour away from your phone each day, a meal with others each day, curating media to 4 hours each week as well as more obviously religious habits like daily prayer and a sabbath day.&lt;/p&gt;
&lt;p&gt;Each book offers these habits as &amp;ldquo;focusing tools&amp;rdquo;, ways to spend time on what is important and focus on the &amp;ldquo;good life&amp;rdquo;.  So what is the &amp;ldquo;good life&amp;rdquo;? Well&amp;hellip;&lt;/p&gt;
&lt;h3 id=&#34;a-subtly-different-motivation&#34;&gt;A Subtly Different Motivation&lt;/h3&gt;
&lt;p&gt;The biggest difference between Deep Work and The Common Rule is what they&amp;rsquo;re aiming to enable.  What is the &amp;ldquo;good life&amp;rdquo; that we want to unlock as we wade out of the shallows?&lt;/p&gt;
&lt;p&gt;Deep Work sees &amp;ldquo;Deep Work&amp;rdquo; as both a good in itself and a means to career success.  Deep Work allows for craftsmanship and an impact on the world greater than we&amp;rsquo;re normally able to achieve.  And because it is both important and implicitly discouraged by the modern office environment, clearing space for it is a tremendous competitive advantage when it comes to career success.&lt;/p&gt;
&lt;p&gt;The Common Rule is explicitly focused on habits that turn us outward from ourselves; habits like a daily meal with others and a weekly hour of conversation with a friend are about connecting with the people around us, while daily prayer and weekly fasting are about connecting with God.  And ultimately they&amp;rsquo;re about health: when we connect well with God and others, we&amp;rsquo;re able to live in a way where we can accept our limitations and thrive where we are.&lt;/p&gt;
&lt;p&gt;I don&amp;rsquo;t think the 2 philosophies are incompatible per say: you can work efficiently at work while valuing your relationships, as long as you&amp;rsquo;re willing to accept the inherent limitations of the 24 hour day.  But reading these 2 books back to back reminded me that &amp;ldquo;efficiency&amp;rdquo; is never an end to itself.  It&amp;rsquo;s always important to make sure you&amp;rsquo;re heading efficiently in the right direction.&lt;/p&gt;
&lt;h3 id=&#34;recommendation&#34;&gt;Recommendation&lt;/h3&gt;
&lt;p&gt;I highly recommend both of these books.  They are full of fantastic suggestions that I plan on implementing over time (I&amp;rsquo;m trying to avoid my classic blunder of trying to change everything about my life at once and look for bits and pieces to attempt first). But as you take in the ideas, make sure to reflect on what the &amp;ldquo;good life&amp;rdquo; looks like to you.&lt;/p&gt;
&lt;h4 id=&#34;amazon-links&#34;&gt;Amazon Links&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://amzn.to/2TqwDeR&#34;&gt;Deep Work by Cal Newport&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://amzn.to/2F0AIgV&#34;&gt;The Common Rule by Justin Earley&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>The Importance of Writing For Software Developers</title>
      <link>https://benmccormick.org/2019/03/01/190000.html</link>
      <pubDate>Fri, 01 Mar 2019 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2019/03/02/190000.html</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Once somebody hits a minimum threshold of technical skill to hold a job in the industry, about 80% of their ability to succeed in Software Development is determined by their communication and people skills, not their technical abilities&lt;/p&gt;
&lt;p&gt;- &lt;em&gt;Me, Christmas 2018&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I think I caught my sister in law by surprise a bit when I answered her questions about the importance of writing in my job that way.  She&amp;rsquo;s an assistant professor who teaches writing to college students, and has found that her students pursuing technical degrees generally fail to see the value in learning to write.  The contrast between their expectations and my perspective after a decade working in software was strong.  I promised her at the time that I&amp;rsquo;d write down some thoughts on why writing skills are valuable for software engineers.  So here it is, 6 reasons that writing skills are crucial for working in the tech industry&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;h4 id=&#34;1-you-will-write-every-day&#34;&gt;1. You will write every day&lt;/h4&gt;
&lt;p&gt;Every industry has truths that are obvious to those who have spent time working in the industry, but may be surprising to those on the outside.  One such truth for software engineers: our jobs involve an awful lot of writing.  Here are a few types of writing that I&amp;rsquo;ve done daily or weekly for the last decade:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Discussing technical implementations through chat apps like slack&lt;/li&gt;
&lt;li&gt;Writing Bug Reports&lt;/li&gt;
&lt;li&gt;Writing comments in my code and technical documentation to help others and my future self understand what was done&lt;/li&gt;
&lt;li&gt;Writing reviews of other developers code to help our team improve and coordinate on best practices&lt;/li&gt;
&lt;li&gt;Answering questions from less technical employees or clients, often through email or slack.&lt;/li&gt;
&lt;li&gt;Creating design documents for complex work during planning times&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;That list is illustrative but not exhaustive.  Any software engineer who wishes to build software that is used by others will end up doing plenty of writing.&lt;/p&gt;
&lt;h4 id=&#34;2-the-ability-to-explain-complex-topics-will-set-you-apart&#34;&gt;2. The ability to explain complex topics will set you apart&lt;/h4&gt;
&lt;p&gt;The ability to take a complex topic and explain it in terms that somebody who doesn&amp;rsquo;t have all the background you do can understand is a critical one for software engineers.  This can help negate two of the most frustrating experiences for a developer:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;A business asking for work that doesn&amp;rsquo;t make sense because the business folks don&amp;rsquo;t understand how the product works&lt;/li&gt;
&lt;li&gt;Less experienced members of the the team routinely making mistakes and breaking things because they don&amp;rsquo;t understand how the product works&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Senior engineers who can explain and document complex pieces of software save everyone frustration by helping junior members of the team understand how things work and be more productive, and by aligning business expectations and plans to the reality of how their software systems actually work.  These are hugely valuable activities that can make a big difference in your career.&lt;/p&gt;
&lt;h4 id=&#34;3-writing-will-help-you-find-a-better-job&#34;&gt;3. Writing will help you find a (better) job&lt;/h4&gt;
&lt;p&gt;When I&amp;rsquo;ve interviewed software engineers, I see a variety of problems: they fail to present their strengths, don&amp;rsquo;t manage to show a sincere interest in the job, and get caught flat-footed on fairly standard questions.  Most of these mistakes come down to a lack of preparation, not tailoring their message to their audience, and not knowing how to structure the information they know about themselves in a compelling way.  These are the skills that you&amp;rsquo;ll learn from a good class on writing, and develop through practice writing.&lt;/p&gt;
&lt;p&gt;Interviews are important, especially early on in your career.  Your compensation as you go throughout your career tends to be anchored to where you started, especially if you stay one place for a long time.  An increase of $5,000 in salary on a job you take today would mean an additional $92,000 of accumulated income over the next 15 years assuming a salary increase rate of 3% a year&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;In addition if you write publicly on a blog like this, it can help you show proof of your knowledge in a way that a resume never will.  Not everybody needs to be publicly blogging, but if that appeals to you it can be a great career booster.&lt;/p&gt;
&lt;h4 id=&#34;4-remote-work-increases-the-importance-of-writing&#34;&gt;4. Remote work increases the importance of writing&lt;/h4&gt;
&lt;p&gt;One of the biggest trends in the tech industry these days is the &lt;a href=&#34;https://www.zenefits.com/blog/remote-workforce-rise/&#34;&gt;rise of remote work&lt;/a&gt;. More teams are embracing partial remote work, and there are major companies like Buffer, Invision and GitLab that are entirely remote.  Remote work is partially enabled by video chat technology, but written communication is the lifeblood of a successful remote team. Collaborating via tools like Slack, Github, Trello and Jira is part of most teams&#39; workflows, but when everybody is remote, being able to express yourself clearly on these platforms is critical.&lt;/p&gt;
&lt;h4 id=&#34;5-your-career-trajectory-will-depend-on-your-ability-to-influence-and-persuade&#34;&gt;5. Your career trajectory will depend on your ability to influence and persuade&lt;/h4&gt;
&lt;p&gt;Most developers when they begin their first software job will be given a set of tasks to do and the expectation is that they will create work to the spec that somebody else has designed.  They are implementors.  But as a developers career progresses there is an opportunity to be more than an implementor.  Since developers understand the system best, they often have ideas that can help shape product designs.  Developers also often need to work with other teams whose goals may not be completely aligned with their team.  These are not situations where even a senior engineer is likely to have direct authority.  Instead the developers who continue to grow in their careers are those who are able to influence and persuade without authority.&lt;/p&gt;
&lt;p&gt;This is again a skill that writing classes can cultivate.  Persuasive writing practice can help give you the clarity of thought and intuition for structuring arguments that will help both when you&amp;rsquo;re trying to make a point through writing or doing it verbally.&lt;/p&gt;
&lt;h4 id=&#34;6-writing-skills-translate-to-writing-code&#34;&gt;6. Writing skills translate to writing code&lt;/h4&gt;
&lt;p&gt;This last one is really specific to software engineering, but I&amp;rsquo;ve found that applying writing principles to code has helped me write more maintainable code.  Most code written in a professional context will be read many times by other people (or by the original author after they have long lost track of their original context).  Being able to write code that can be understood by both a computer and by human beings is a skill developed over time, but many of the same &amp;ldquo;brain muscles&amp;rdquo; that you develop in writing prose can be applied to code: it&amp;rsquo;s important to know your audience, structure your information in a logical manner, and use judgement when finding just the right phrase (or code structure) for a situation.  That could be a whole post in itself.&lt;/p&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;I write based on the tech industry and software development specifically because that is what I have lived, but most of these points should be equally applicable to any engineering career and would likely require very little modification for science and research as well.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;Ok real world promotion rates in the tech industry are likely to be choppier than that, but the example holds.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>Strategic Coding</title>
      <link>https://benmccormick.org/2019/02/17/190000.html</link>
      <pubDate>Sun, 17 Feb 2019 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2019/02/18/190000.html</guid>
      <description>&lt;p&gt;I recently read &lt;a href=&#34;https://amzn.to/2Elk5g8&#34;&gt;A Philosophy Of Software Design&lt;/a&gt; by John Ousterhout.  In an early chapter he paints a picture of a &amp;ldquo;tactical tornado&amp;rdquo; programmer, a programmer who is always focused on solving the current problem by the most expedient method possible, with no thought to the long term implications.  I suspect anyone with even a few years in the programming has seen programmers like this, and has also from time to time written &amp;ldquo;tactical&amp;rdquo; code like this themselves.  Ousterhout&amp;rsquo;s recommendation is instead to write code strategically rather than tactically, taking more up front time to plan the structure for the benefit of longer term productivity.&lt;/p&gt;
&lt;p&gt;Ousterhout focuses his examination of tactical vs strategic coding on the issue of complexity.  Complexity as he defines it is anything that makes the system difficult to work with.  It is the root issue behind much of the &lt;em&gt;ease of change&lt;/em&gt; concern I identified in my &lt;a href=&#34;https://benmccormick.org/2019/01/07/the-concerns-of-fe-architecture/&#34;&gt;recent post&lt;/a&gt;.  But we can expand this to encompass all of the front end concerns.  We can easily impact reliability, performance, ease of change, accessibility, security and capability when we make short hand tradeoffs.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s consider the problem of getting a new sign up page set up for a site.  There are several different approaches we could take.  By far the simplest is a basic HTML page using normal CSS and little or no JavaScript, that posts to a backend service after the signup and then redirects to a different static page.  We could set this up on S3 or any other service that will host static files.  On the other extreme, we could set up a new server side rendered Typescript-based React application that uses Next.js to give us server side rendering, which we deploy using Docker and a fully automated CI build system with chatbot ops.  Which one of these approaches is better?&lt;/p&gt;
&lt;p&gt;A tactical tornado would likely prefer the first solution.  They could get the whole thing up and running in an hour, stamp it and call it done.  Other developers might be attracted to the &lt;em&gt;cool&lt;/em&gt; approach and want to avoid the &amp;ldquo;outdated&amp;rdquo; approach.  But we can only really answer the question by stepping back and asking some questions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;What is the future of this application?  Is this a standalone page, or the first page in a larger application?&lt;/li&gt;
&lt;li&gt;What feature requests are we likely to get for the page?  Is it probable that we&amp;rsquo;ll eventually need form validation, dynamic success and failure states, complex behavior that depends on the use case?&lt;/li&gt;
&lt;li&gt;What browsers are we supporting&lt;/li&gt;
&lt;li&gt;What are our performance benchmarks?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Questions like that can tell us when we&amp;rsquo;ll benefit from an up front investment in certain areas, and when it&amp;rsquo;s wiser to be quick and dirty.  They also allow us to evaluate whether any options we&amp;rsquo;re considering might cut us off from achieving long term goals.  For instance, if we know that we&amp;rsquo;ll eventually need to scale this site into a large application with responsive interactions, personalized content and information maintained between page loads, building this out as a series of static pages which POST to a backend would eventually limit our capabilities or require a refactor.  But if this is only a one-off landing page for an event happening next week that won&amp;rsquo;t be maintained beyond that point, developing a long-term maintenance strategy would be wasted effort.  This is &lt;em&gt;strategic coding&lt;/em&gt;, and it doesn&amp;rsquo;t stop at the beginning of a project, it&amp;rsquo;s an ongoing mindset that you can take as you add each new feature to an application.&lt;/p&gt;
&lt;p&gt;Ousterhout makes a case that aligns with my experience, that strategic programming is a long term winner.  I&amp;rsquo;ve seen that over time improvements to ease of change will often help a team save time lost, significant hits to performance, security, reliability may hurt them more than a fast solution saves them, and solutions that unreasonably limit us in terms of system capability or accessibility will ultimately get rejected.  The weasel words there exist for a reason&amp;hellip; sometimes it really is the best idea to just get something working.  But a strategic programmer will understand the context of their project, and make wise choices about where and how to invest in the codebase.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;It is possible to program either tactically or strategically&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tactical programming is focused on solving the immediate problem as quickly as possible&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Strategic coding considers the context of the problem, and any architectural concerns involved in a change&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Strategic coding doesn&amp;rsquo;t mean never hacking and always investing, it means letting context inform the amount and direction of investment in a codebase&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;PS: I put a &lt;a href=&#34;https://benmccormick.org/2018/12/31/book-review-philosophy-of-software-design/&#34;&gt;full review of A Philosophy of Software Design&lt;/a&gt; up on the site a few weeks ago.  Check it out :)&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Reusable Code In React: Inheritance, Composition, Decorators and Mixins</title>
      <link>https://benmccormick.org/2019/02/10/190000.html</link>
      <pubDate>Sun, 10 Feb 2019 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2019/02/11/190000.html</guid>
      <description>&lt;p&gt;Once you get past the initial complexity it creates by bucking conventions, React is the most developer friendly UI library I have ever used.  A big reason for that is the way it uses and encourages a variety of patterns to share codes and concepts across a code base. Let&amp;rsquo;s look at how 4 traditional code re-use patterns are used by React and in the React ecosystem, using a simple counter example to explore why each pattern is used.&lt;/p&gt;
&lt;h4 id=&#34;inheritance&#34;&gt;Inheritance&lt;/h4&gt;
&lt;p&gt;Inheritance is a code-reuse technique associated with object oriented programming.  If you&amp;rsquo;re like me and learned to program in school using Java, it probably is one of the very first Computer Science concepts you learned.  For self-taught JavaScript devs it may be much less familiar.  Inheritance is a pattern for extending an existing class or object with additional methods or data, possibly overriding the implementations of other methods in the process.  A classic example of inheritance looks like this in JS:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;
&lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; Automobile {
    constructor() {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.vehicleName &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; automobile;
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.numWheels &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;null&lt;/span&gt;;
    }
    printNumWheels() {
        console.log(&lt;span style=&#34;color:#f1fa8c&#34;&gt;`This &lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.vehicleName&lt;span style=&#34;color:#f1fa8c&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt; has &lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.numWheels&lt;span style=&#34;color:#f1fa8c&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt; wheels`&lt;/span&gt;);
    }
}

&lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; Car &lt;span style=&#34;color:#ff79c6&#34;&gt;extends&lt;/span&gt; Automobile {
    constructor() {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;super&lt;/span&gt;(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;);
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.vehicleName &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;car&amp;#39;&lt;/span&gt;;
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.numWheels &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;4&lt;/span&gt;;
    }
}

&lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; Bicycle &lt;span style=&#34;color:#ff79c6&#34;&gt;extends&lt;/span&gt; Automobile {
    constructor() {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;super&lt;/span&gt;(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;);
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.vehicleName &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;bike&amp;#39;&lt;/span&gt;;
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.numWheels &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt;;
    }
}

&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; car &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; Car();
&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; bike &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; Bicycle();
car.printNumWheels() &lt;span style=&#34;color:#6272a4&#34;&gt;// This car has 4 wheels
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;bike.printNumWheels() &lt;span style=&#34;color:#6272a4&#34;&gt;// This bike has 2 wheels
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Inheritance is useful for highly structured objects where you have a lot of shared behavior across similar but slightly different objects and you want to be able to treat all of the objects as interchangeable from an API perspective. This is especially valuable when that interchangeable API is well defined and unlikely to change too much.  However it tends to lead to brittle structures when nested across multiple levels, and is a poor fit when dealing with dissimilar objects that need to share a few behaviors.&lt;/p&gt;
&lt;p&gt;React Components are objects that we want to treat as interchangeable from an outside API perspective, and they have well defined points where behavior may need to be different between components but don&amp;rsquo;t always need to differ: the lifecycle methods like render, componentDidMount, componentWillUnmount, etc.  Thus React relies on a single level of inheritance as the foundation of its class components.  Class components inherit from React.Component, and only implement the life cycle methods that they&amp;rsquo;re interested in.  But all of them inherit useable setState and forceUpdate functions, and React can verify that by checking the &lt;code&gt;isReactComponent&lt;/code&gt; property on the object.&lt;/p&gt;
&lt;p&gt;Here is a basic counter component.  Notice how we don&amp;rsquo;t have to define &lt;code&gt;setState&lt;/code&gt; on our &lt;code&gt;Counter&lt;/code&gt; class.  Instead it inherits it from React.Component.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;//counter.js
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; Counter &lt;span style=&#34;color:#ff79c6&#34;&gt;extends&lt;/span&gt; React.Component {
    constructor(props) {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;super&lt;/span&gt;(props);
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.state &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {
            count&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;0&lt;/span&gt;,
        }
    }
    render() {
        &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; {count} &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.state;
        &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; increment &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; () =&amp;gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.setState(state =&amp;gt; {
            &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; {
               count&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; state.count &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;
            };
        });
        &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;div className&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;fancy-layout&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;
            &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;div className&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;fancy-display&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;
                Current Count&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; {count}
            &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;/div&amp;gt;
            &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;button
                className&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;incrementCounterBtn fancy-btn&amp;#34;&lt;/span&gt;
                onClick&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;{increment}
            &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;Increment&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;/button&amp;gt;
        &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;/div&amp;gt;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Outside of this single layer of inheritance for defining Class components, inheritance isn&amp;rsquo;t used much in React development.  It turns out that better patterns have emerged for sharing application code.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Inheritance Pattern&lt;/strong&gt;: Used sparingly to share common code across React class components.&lt;/p&gt;
&lt;h4 id=&#34;composition&#34;&gt;Composition&lt;/h4&gt;
&lt;p&gt;Composition is a code reuse technique where a larger object is created by combining multiple smaller objects.  Composition is in some ways the natural pattern of the browser, as HTML uses it.  We build a table in html, not by adding a bunch of configuration to a single table object, but by combining a &lt;code&gt;table&lt;/code&gt; tag with &lt;code&gt;tr&lt;/code&gt;s, &lt;code&gt;td&lt;/code&gt;s, and &lt;code&gt;th&lt;/code&gt;s like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&amp;lt;&lt;span style=&#34;color:#ff79c6&#34;&gt;table&lt;/span&gt;&amp;gt;
    &amp;lt;&lt;span style=&#34;color:#ff79c6&#34;&gt;thead&lt;/span&gt;&amp;gt;
        &amp;lt;&lt;span style=&#34;color:#ff79c6&#34;&gt;tr&lt;/span&gt;&amp;gt;&amp;lt;&lt;span style=&#34;color:#ff79c6&#34;&gt;th&lt;/span&gt;&amp;gt;Web Framework&amp;lt;/&lt;span style=&#34;color:#ff79c6&#34;&gt;th&lt;/span&gt;&amp;gt;&amp;lt;&lt;span style=&#34;color:#ff79c6&#34;&gt;th&lt;/span&gt;&amp;gt;Language&amp;lt;/&lt;span style=&#34;color:#ff79c6&#34;&gt;th&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style=&#34;color:#ff79c6&#34;&gt;tr&lt;/span&gt;&amp;gt;
    &amp;lt;/&lt;span style=&#34;color:#ff79c6&#34;&gt;thead&lt;/span&gt;&amp;gt;
    &amp;lt;&lt;span style=&#34;color:#ff79c6&#34;&gt;tbody&lt;/span&gt;&amp;gt;
        &amp;lt;&lt;span style=&#34;color:#ff79c6&#34;&gt;tr&lt;/span&gt;&amp;gt;&amp;lt;&lt;span style=&#34;color:#ff79c6&#34;&gt;th&lt;/span&gt;&amp;gt;Rails&amp;lt;/&lt;span style=&#34;color:#ff79c6&#34;&gt;th&lt;/span&gt;&amp;gt;&amp;lt;&lt;span style=&#34;color:#ff79c6&#34;&gt;th&lt;/span&gt;&amp;gt;Ruby&amp;lt;/&lt;span style=&#34;color:#ff79c6&#34;&gt;th&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style=&#34;color:#ff79c6&#34;&gt;tr&lt;/span&gt;&amp;gt;
        &amp;lt;&lt;span style=&#34;color:#ff79c6&#34;&gt;tr&lt;/span&gt;&amp;gt;&amp;lt;&lt;span style=&#34;color:#ff79c6&#34;&gt;th&lt;/span&gt;&amp;gt;Django&amp;lt;/&lt;span style=&#34;color:#ff79c6&#34;&gt;th&lt;/span&gt;&amp;gt;&amp;lt;&lt;span style=&#34;color:#ff79c6&#34;&gt;th&lt;/span&gt;&amp;gt;Python&amp;lt;/&lt;span style=&#34;color:#ff79c6&#34;&gt;th&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style=&#34;color:#ff79c6&#34;&gt;tr&lt;/span&gt;&amp;gt;
        &amp;lt;&lt;span style=&#34;color:#ff79c6&#34;&gt;tr&lt;/span&gt;&amp;gt;&amp;lt;&lt;span style=&#34;color:#ff79c6&#34;&gt;th&lt;/span&gt;&amp;gt;Flask&amp;lt;/&lt;span style=&#34;color:#ff79c6&#34;&gt;th&lt;/span&gt;&amp;gt;&amp;lt;&lt;span style=&#34;color:#ff79c6&#34;&gt;th&lt;/span&gt;&amp;gt;Python&amp;lt;/&lt;span style=&#34;color:#ff79c6&#34;&gt;th&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style=&#34;color:#ff79c6&#34;&gt;tr&lt;/span&gt;&amp;gt;
        &amp;lt;&lt;span style=&#34;color:#ff79c6&#34;&gt;tr&lt;/span&gt;&amp;gt;&amp;lt;&lt;span style=&#34;color:#ff79c6&#34;&gt;th&lt;/span&gt;&amp;gt;Play&amp;lt;/&lt;span style=&#34;color:#ff79c6&#34;&gt;th&lt;/span&gt;&amp;gt;&amp;lt;&lt;span style=&#34;color:#ff79c6&#34;&gt;th&lt;/span&gt;&amp;gt;Scala&amp;lt;/&lt;span style=&#34;color:#ff79c6&#34;&gt;th&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style=&#34;color:#ff79c6&#34;&gt;tr&lt;/span&gt;&amp;gt;
        &amp;lt;&lt;span style=&#34;color:#ff79c6&#34;&gt;tr&lt;/span&gt;&amp;gt;&amp;lt;&lt;span style=&#34;color:#ff79c6&#34;&gt;th&lt;/span&gt;&amp;gt;Play&amp;lt;/&lt;span style=&#34;color:#ff79c6&#34;&gt;th&lt;/span&gt;&amp;gt;&amp;lt;&lt;span style=&#34;color:#ff79c6&#34;&gt;th&lt;/span&gt;&amp;gt;Java&amp;lt;/&lt;span style=&#34;color:#ff79c6&#34;&gt;th&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style=&#34;color:#ff79c6&#34;&gt;tr&lt;/span&gt;&amp;gt;
        &amp;lt;&lt;span style=&#34;color:#ff79c6&#34;&gt;tr&lt;/span&gt;&amp;gt;&amp;lt;&lt;span style=&#34;color:#ff79c6&#34;&gt;th&lt;/span&gt;&amp;gt;Express&amp;lt;/&lt;span style=&#34;color:#ff79c6&#34;&gt;th&lt;/span&gt;&amp;gt;&amp;lt;&lt;span style=&#34;color:#ff79c6&#34;&gt;th&lt;/span&gt;&amp;gt;JavaScript&amp;lt;/&lt;span style=&#34;color:#ff79c6&#34;&gt;th&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style=&#34;color:#ff79c6&#34;&gt;tr&lt;/span&gt;&amp;gt;
    &amp;lt;/&lt;span style=&#34;color:#ff79c6&#34;&gt;tbody&lt;/span&gt;&amp;gt;
&amp;lt;/&lt;span style=&#34;color:#ff79c6&#34;&gt;table&lt;/span&gt;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;React has fully embraced the HTML style of composing UI components, and it takes thing to the next level by allowing components to be stateful and pass values down into children.  For instance, if we wanted to split the counter component above into a separate control and display, perhaps using a standard set of UI components we could do it by extracting &lt;code&gt;FancyLayout&lt;/code&gt;, &lt;code&gt;FancyButton&lt;/code&gt; and &lt;code&gt;FancyDisplay&lt;/code&gt; elements out into their own components and then composing them back into a single counter component.  This type of thing is useful for creating and reusing standard UI elements, and might look something like the following:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;// UI components defined elsewhere
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; FancyLayout &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; ({children}) =&amp;gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;div className&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;fancy-layout&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;{children}&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;/div&amp;gt;;
&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; FancyDisplay &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; ({children}) =&amp;gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;div className&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;fancy-display&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;{children}&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;/div&amp;gt;;
&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; FancyButton &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; ({children, className, onClick}) =&amp;gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;button
    className&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;{&lt;span style=&#34;color:#f1fa8c&#34;&gt;`fancy-layout &lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;${&lt;/span&gt;className&lt;span style=&#34;color:#f1fa8c&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;`&lt;/span&gt;}
    onClick&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;{onClick}
    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;
        {children}
    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;/button&amp;gt;;


&lt;span style=&#34;color:#6272a4&#34;&gt;// counter.js
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; Counter &lt;span style=&#34;color:#ff79c6&#34;&gt;extends&lt;/span&gt; React.Component {
    constructor(props) {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;super&lt;/span&gt;(props);
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.state &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {
            count&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;0&lt;/span&gt;,
        }
    }
    render() {
        &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; {count} &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.state;
         &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; increment &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; () =&amp;gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.setState(state =&amp;gt; {
            &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; {
               count&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; state.count &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;
            };
        });
        &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;FancyLayout&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;
            &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;FancyDisplay&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;
                Current Count&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; {count}
            &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;/FancyDisplay&amp;gt;
            &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;FancyButton
                className&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;incrementCounterBtn&amp;#34;&lt;/span&gt;
                onClick&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;{increment}
            &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;Increment&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;/FancyButton&amp;gt;
        &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;/FancyLayout&amp;gt;;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In this example we now have 4 components instead of one.  Three of them are laser-focused on defining a specific element type, and are &amp;ldquo;display only&amp;rdquo; with no logic of their own.  The 4th contains all of our logic and defines how the display pieces come together.&lt;/p&gt;
&lt;p&gt;In the seminal 1994 book &lt;a href=&#34;https://amzn.to/2WDhncv&#34;&gt;Design Patterns&lt;/a&gt; the authors argue that composition should be strictly preferred over inheritance where possible because it creates less tightly coupled objects, and encourages designs where objects are small, focused and readable.  Composition also lets us hide complexity inside of child objects, because parent components only have to concern themselves with the APIs exposed by those child objects.  One of the keys to React&amp;rsquo;s success has been making this type of composition clean and painless by encouraging strong component interfaces and utilizing JSX to provide a comfortable syntax for describing composed UIs while keeping all component concerns in the same place&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;It is worth noting that after this refactor, our counting logic is still tightly tied to the layout of our counter component.  Let&amp;rsquo;s explore 2 more patterns that can help us extract our logic from the display completely.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Composition Pattern&lt;/strong&gt;: The core pattern for separating concerns while creating complex UIs with React.&lt;/p&gt;
&lt;h4 id=&#34;decorators&#34;&gt;Decorators&lt;/h4&gt;
&lt;p&gt;Decorators are a pattern for editing an instance of a class to give it additional behaviors than it had previously.  In contrast to inheritance, decorators are not part of the class definition, but are modifications to the class at run time to allow a subset of objects to have additional data or behavior &lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;.  In classic object oriented programming, this was implemented by having a decorator class that shared an interface with the class to be decorated, and called its methods through to that class, with additional behavior before or after the pass-through.  The React community has generally implemented this pattern slightly differently, by writing functions that take a component class and return a new component class that calls through to the original component, possibly with additional props passed in, extra components rendered around it, or conditional logic that causes it not to render in some cases.  The React community generally refers to this pattern as &lt;a href=&#34;https://reactjs.org/docs/higher-order-components.html&#34;&gt;Higher Order Components&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s an example of using a higher order component called &lt;code&gt;withCounter&lt;/code&gt; to separate out the display and logic portions of our Counter component.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; withCounter &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; WrappedComponent =&amp;gt; {
   &lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; ComponentWithCounter &lt;span style=&#34;color:#ff79c6&#34;&gt;extends&lt;/span&gt; React.Component {
      constructor(props) {
         &lt;span style=&#34;color:#ff79c6&#34;&gt;super&lt;/span&gt;(props);
         &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.state &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {
            count&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;0&lt;/span&gt;
         };
         &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.increment &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; () =&amp;gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.setState(state =&amp;gt; {
            &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; {
               count&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; state.count &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;
            };
         });
      }

      render() {
         &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; {count} &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.state;
         &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;WrappedComponent count&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;{count} increment&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;{&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.increment} &lt;span style=&#34;color:#ff79c6&#34;&gt;/&amp;gt;&lt;/span&gt;
      }
  }
  &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; ComponentWithCounter;
};

&lt;span style=&#34;color:#6272a4&#34;&gt;// counter.js
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;
&lt;span style=&#34;color:#6272a4&#34;&gt;// this is a display only version of the component with no logic
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;// very easy to test and simple to change
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; CounterDisplay &lt;span style=&#34;color:#ff79c6&#34;&gt;extends&lt;/span&gt; React.Component {
    render() {
        &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; {count, increment} &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.props;
        &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;FancyLayout&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;
            &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;FancyDisplay&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;
                Current Count&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; {count}
            &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;/FancyDisplay&amp;gt;
            &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;FancyButton
                className&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;incrementCounterBtn&amp;#34;&lt;/span&gt;
                onClick&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;{increment}
            &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;Increment&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;/FancyButton&amp;gt;
        &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;/FancyLayout&amp;gt;;
    }
}

&lt;span style=&#34;color:#6272a4&#34;&gt;// this adds the logic back to the display only version
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; Counter &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; withCounter(CounterDisplay);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now we&amp;rsquo;ve taken our refactored &lt;code&gt;Counter&lt;/code&gt; and split it into 2 more pieces.  The display logic remains in a simplified &lt;code&gt;CounterDisplay&lt;/code&gt; component that doesn&amp;rsquo;t have any state or business logic of its own.  &lt;code&gt;CounterDisplay&lt;/code&gt; takes 2 new props, &lt;code&gt;count&lt;/code&gt; and &lt;code&gt;increment&lt;/code&gt; that allow it to implement the counting logic without having to know how it is implemented.&lt;/p&gt;
&lt;p&gt;Meanwhile, we split the counting logic out into a Higher Order Component.  &lt;code&gt;withCounter&lt;/code&gt; takes a React component and wraps it with another component that is solely responsible for keeping track of counts and providing the increment function.  In this case that is our CounterDisplay component, but if we decided we wanted to also have fancy counters that incremented when the user clicked a checkbox or hovered over a box or typed the word increment, it would be easy to reuse this logic.&lt;/p&gt;
&lt;p&gt;Higher Order Components helped many React libraries like Redux and React Router define elegant APIs when they first came on the scene, but they&amp;rsquo;ve always been a power user technique.  There are many ways to screw them up, and although they allow for theoretical loose coupling, they still require a certain level of shared understanding between the decorator and decoratee, including knowing what props to make available, whether any methods have to be proxied through to the decorated component, and more.  The community as a whole has tended to favor render props over the past year&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;, and now looks poised to move towards our 4th pattern: mixins.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Decorator Pattern&lt;/strong&gt;: Used to provide a nice interface for separating out logic shared by multiple components and centralizing it.&lt;/p&gt;
&lt;h4 id=&#34;mixins&#34;&gt;Mixins&lt;/h4&gt;
&lt;p&gt;The newest pattern that React has added to its bag of code reuse tricks is also one of the oldest.  In older versions of React there was a feature called &amp;ldquo;mixins&amp;rdquo; that was &lt;a href=&#34;https://reactjs.org/blog/2016/07/13/mixins-considered-harmful.html&#34;&gt;later deprecated due to its ease of mis-use&lt;/a&gt;.  &amp;ldquo;Mixins&amp;rdquo; are gone now, but the &amp;ldquo;Mixin pattern&amp;rdquo; is back!  React is in the process of introducing &lt;a href=&#34;https://reactjs.org/docs/hooks-intro.html&#34;&gt;hooks&lt;/a&gt;, a new way of doing mixins.&lt;/p&gt;
&lt;p&gt;So first, what is a mixin?  It is yet another way of defining shared behavior onto a class, in this case providing methods and/or data that are &amp;ldquo;mixed in&amp;rdquo; to one or more classes.  It differs from inheritance because a class using a mixin doesn&amp;rsquo;t have to use the mixin as a parent class, and the class may use several mixins at once.  Mixins that are used together in one class may not be used together in another.  Mixins also different from the decorator pattern, because the mixin is part of the class definition, not something that is applied dynamically later.&lt;/p&gt;
&lt;p&gt;Mixins are useful when you have classes with different purposes that shouldn&amp;rsquo;t share an inheritance tree but do have some shared behavior.  In practice though they have historically been tricky to use because it is easy to tightly bind mixin code to the implementation of the code that it is mixed into.  Poorly implemented Mixins can result in naming collisions, inflexible code, and hard to trace errors.&lt;/p&gt;
&lt;p&gt;React Hooks may not look like mixins, since they are used in a function, not a class.  But they fill the exact same role as traditional mixins, while avoiding some of the footguns (no naming collisions!).  Let&amp;rsquo;s look at an example from Dan Abramov&amp;rsquo;s blog post &lt;a href=&#34;https://medium.com/@dan_abramov/making-sense-of-react-hooks-fdbde8803889&#34;&gt;introducing hooks&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt; useWindowWidth() {
  &lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; [width, setWidth] &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; useState(&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;window&lt;/span&gt;.innerWidth);

  useEffect(() =&amp;gt; {
    &lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; handleResize &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; () =&amp;gt; setWidth(&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;window&lt;/span&gt;.innerWidth);
    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;window&lt;/span&gt;.addEventListener(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;resize&amp;#39;&lt;/span&gt;, handleResize);
    &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; () =&amp;gt; {
      &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;window&lt;/span&gt;.removeEventListener(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;resize&amp;#39;&lt;/span&gt;, handleResize);
    };
  });

  &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; width;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is a hook that provides the width of the current window to a React component, updating each time the window is resized.  You would use it in practice like this example of a header bar that replaces its menu items with a hamburger menu on smaller screens:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;
&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; Header &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; () =&amp;gt; {
    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; windowWidth &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; useWindowWidth();
    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; showHamburgerMenu &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; windowWidth &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;800&lt;/span&gt;;

    &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; (&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;div&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;
        &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;Logo&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;
        {showHamburgerMenu &lt;span style=&#34;color:#ff79c6&#34;&gt;?&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;HamburgerMenu&lt;span style=&#34;color:#ff79c6&#34;&gt;/&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;MenuItems&lt;span style=&#34;color:#ff79c6&#34;&gt;/&amp;gt;&lt;/span&gt;}
    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;/div&amp;gt;)
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This usage is different from a normal helper function, because it enhances the component; because this is using React&amp;rsquo;s state code within the hook, this component will automatically update when needed.  So it is a way of reusing component behavior like Higher Order Components.  But we lose a lot of the disadvantages of HOCs.   &lt;code&gt;useWindowWidth&lt;/code&gt; and &lt;code&gt;Header&lt;/code&gt; are extremely loosely coupled.  &lt;code&gt;useWindowWidth&lt;/code&gt; doesn&amp;rsquo;t know anything about the header bar structure or logic, or the rules for when things should show.  It is only providing information.  At the same time, if we refactored it to get the window size in some other way, or to throttle updates, we wouldn&amp;rsquo;t have to change anything about &lt;code&gt;Header&lt;/code&gt;, since all it knows is that &lt;code&gt;useWindowWidth&lt;/code&gt; will occasionally provide it an updated windowWidth.&lt;/p&gt;
&lt;p&gt;The functional style makes this look different than a traditional object oriented &amp;ldquo;mixin pattern&amp;rdquo; example, but it is using the same concepts and solving the same problems.  This way of doing things has advantages; because it is &amp;ldquo;just a function&amp;rdquo; that gets called, we never need to worry about it having a naming collision with a different class method, or having to be aware of the structure of the outer component.  If it needs component specific information, we can just pass it an argument.&lt;/p&gt;
&lt;p&gt;With Hooks, we can create a much cleaner version of our Higher Order Component example from the decorators section.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;// defined in a library file
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; useIncrement &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; (initial &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;0&lt;/span&gt;) =&amp;gt; {
   &lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; [count, increment] &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; useReducer(val =&amp;gt; val &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;, initial);
   &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; [count, increment];
}

&lt;span style=&#34;color:#6272a4&#34;&gt;// counter.js
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; Counter &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; () =&amp;gt; {
    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; [count, increment] &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; useIncrement();
    &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;FancyLayout&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;
        &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;FancyDisplay&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;
            Current Count&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; {count}
        &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;/FancyDisplay&amp;gt;
        &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;FancyButton
            className&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;incrementCounterBtn&amp;#34;&lt;/span&gt;
            onClick&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;{increment}
        &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;Increment&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;/FancyButton&amp;gt;
    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;/FancyLayout&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;As with decorators we&amp;rsquo;ve extracted the logic in a reusable form, but we&amp;rsquo;ve done so with much less boilerplate.  I&amp;rsquo;ve removed the intermediate &lt;code&gt;CounterDisplay&lt;/code&gt; here, because if we&amp;rsquo;re not using it for anything else, it is easy enough to just include the hook directly in the definition.  But if we wanted, we could easily use that &lt;code&gt;CounterDisplay&lt;/code&gt; component with a hooks enabled wrapper component:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; Counter &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; () =&amp;gt; {
    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; [count, increment] &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; useIncrement();
    &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;CounterDisplay count&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;{count} increment&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;{increment}&lt;span style=&#34;color:#ff79c6&#34;&gt;/&amp;gt;&lt;/span&gt;;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Mixin Pattern&lt;/strong&gt;: Hooks use a variation on the Mixin pattern to allow sharing related behavior and data between unrelated function components easily.&lt;/p&gt;
&lt;h3 id=&#34;summary&#34;&gt;Summary&lt;/h3&gt;
&lt;p&gt;If I took one thing out of this analysis personally, it was a renewed appreciation for considering the needs of a situation and finding the right approach for the job, rather than trying to fit every problem to my favorite solution.  I&amp;rsquo;m over 2000 words and I haven&amp;rsquo;t even addressed all the different strategies React and the React community use for code re-use. &lt;em&gt;Sorry render props&lt;/em&gt; 😢.   So next time you run into an architecture problem, consider a few different solutions and their tradeoffs.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;React uses a variety of patterns for code reuse.
&lt;strong&gt;Inheritance Pattern&lt;/strong&gt;: Used sparingly to share common code across React class components.
&lt;strong&gt;Composition Pattern&lt;/strong&gt;: The core pattern for separating concerns while creating complex UIs with React.
&lt;strong&gt;Decorator Pattern&lt;/strong&gt;: Used to provide a nice interface for separating out logic shared by multiple components and centralizing it.
&lt;strong&gt;Mixin Pattern&lt;/strong&gt;: Hooks use a variation on the Mixin pattern to allow sharing related behavior and data between unrelated function components easily.&lt;/p&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;Clunky JS based interfaces for specifying child components are visually difficult to scan and understand, while solutions that use external template files spread logic about a single component to multiple files, making it harder to keep everything in the developers head.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;Note that the decorator pattern is not the same thing as the TC39 proposal to &lt;a href=&#34;https://github.com/tc39/proposal-decorators&#34;&gt;add a decorator syntax to JavaScript&lt;/a&gt;, or the TypeScript feature of the same name.  Both are related to modifying class behavior, but the mechanisms are not the same.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;Render props ultimately qualify as an advanced composition technique and so didn&amp;rsquo;t get their own heading here, but they&amp;rsquo;re definitely worth understanding.&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>Book Review: Info We Trust</title>
      <link>https://benmccormick.org/2019/01/29/190000.html</link>
      <pubDate>Tue, 29 Jan 2019 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2019/01/30/190000.html</guid>
      <description>&lt;p&gt;Sometimes surprises are good. I bought RJ Andrews new book &lt;a href=&#34;https://amzn.to/2Ww9BBl&#34;&gt;Info We Trust&lt;/a&gt; expecting to get some practical tips on how to create better data visualizations. But frankly there’s very little in the way of “how to” in this book. Instead I was treated to a deeply engaging book that’s part history of data visualization, part exploration of human psychology, and 100% a love letter to “data storytelling”, with brief detours into linguistics, museum curation sentence diagramming and propaganda posters. If you’re looking to know when to use a bar chart vs a pie chart in your powerpoint slides, this book will be a disappointment. But if you want to learn how to think deeply about telling stories with data, or just enjoy seeing somebody who loves their topic nerd out about it for 200 pages in a beautiful formatted book, this may be for you.&lt;/p&gt;
&lt;p&gt;Let’s start with that beautiful book. This is not a read that you want to pick up on Kindle. The book is littered with fascinating illustrations, all &lt;a href=&#34;https://infowetrust.com/illustrations/&#34;&gt;hand drawn by the author (!!!)&lt;/a&gt;, and almost every page has interesting quotes, examples and tangents in the marginalia. Here are a few random pages that I snapped with my phone while writing this; it turns out that every single page is this beautiful.&lt;/p&gt;
&lt;p&gt;&lt;img style=&#34;display: block; margin-left: auto; margin-right: auto;&#34; title=&#34;page1.jpg&#34; src=&#34;https://benmccormick.micro.blog/uploads/2022/098a09e5d7.jpg&#34; alt=&#34;Page1&#34; width=&#34;599&#34; height=&#34;449&#34; border=&#34;0&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img style=&#34;display: block; margin-left: auto; margin-right: auto;&#34; title=&#34;page2.jpg&#34; src=&#34;https://benmccormick.micro.blog/uploads/2022/202cdaeb04.jpg&#34; alt=&#34;Page2&#34; width=&#34;599&#34; height=&#34;449&#34; border=&#34;0&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img style=&#34;display: block; margin-left: auto; margin-right: auto;&#34; title=&#34;page3.jpg&#34; src=&#34;https://benmccormick.micro.blog/uploads/2022/3c1c727a2a.jpg&#34; alt=&#34;Page3&#34; width=&#34;600&#34; height=&#34;450&#34; border=&#34;0&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img style=&#34;display: block; margin-left: auto; margin-right: auto;&#34; title=&#34;page4.jpg&#34; src=&#34;https://benmccormick.micro.blog/uploads/2022/c7164c1839.jpg&#34; alt=&#34;Page4&#34; width=&#34;600&#34; height=&#34;450&#34; border=&#34;0&#34; /&gt;&lt;/p&gt;
&lt;p&gt;In addition to the eye candy, Andrews mostly avoids giving readers rules, but instead dives deep into the whys of data storytelling. Things I was left thinking about:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The way I think about bars vs columns differently based on my different assumptions about distance vs stacks of items&lt;/li&gt;
&lt;li&gt;How the plethora of data available in the world today has a cost: our attention. That has left me thinking both about designing interfaces that manage attention, but also how to reclaim my own distracted attention.&lt;/li&gt;
&lt;li&gt;The difference between data and information, and how each can be useful. How in the product I work on we can help users get access to enough raw data to explore on their own, but also give them meaningful “information” derived from that data.&lt;/li&gt;
&lt;li&gt;I was motivated to get better at drawing, and explaining things with images in my day to day work. I don’t do this enough.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If all of that sounds too high level and impractical for you, this is probably not the book for you. But anyone who is already a data viz geek will find something to love, and as somebody who is tangential to the field it certainly expanded my mind and gave me a lot to think about. All in all, this one is easy to recommend. &lt;a href=&#34;https://amzn.to/2Ww9BBl&#34;&gt;Check it out!&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Improving Code Readability With Async/Await</title>
      <link>https://benmccormick.org/2019/01/27/190000.html</link>
      <pubDate>Sun, 27 Jan 2019 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2019/01/28/190000.html</guid>
      <description>&lt;p&gt;When it first became a part of JavaScript, I wasn&amp;rsquo;t sure how much I was going to use async-await.  I could see that it made things prettier in some cases, but I was pretty happy with my promise chains and thought that async-await might just be some extra language baggage.  Since then I&amp;rsquo;ve fully converted; it&amp;rsquo;s one of my favorite features added to the language in recent years.  The reason?  It helps you write code in a linear manner.&lt;/p&gt;
&lt;p&gt;A principle of readable code:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Code should where possible be written in the order in which a reader needs to understand it.1&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;For complex classes, this ideally means that the &amp;ldquo;entry points&amp;rdquo; are towards the top, with the helper methods below to be read as needed&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;. But for &amp;ldquo;linear&amp;rdquo; code that reflects a workflow, we want the code to progress in chronological order as much as possible.  With imperative code that tends to happen by default.  But JavaScript&amp;rsquo;s asynchronous constructs have tended to obscure chronological orders.&lt;/p&gt;
&lt;p&gt;As an example, here is a React component that displays the time remaining in a user session based off of some cookie values.  It checks a cookie on a regular interval to see whether it should display a warning about the session timeout.  Once it is showing the warning, it begins checking the cookie more frequently in order to show a timeout.  Once the session expires, it can stop checking.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;
&lt;span style=&#34;color:#6272a4&#34;&gt;// When time is less than this, we should show warning
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; MAX_TIME_TO_HIDE_WARNING &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1000&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;60&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt;;

&lt;span style=&#34;color:#6272a4&#34;&gt;// intervals in seconds to update timeout count
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; CHECK_INTERVAL_WHEN_HIDING &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;30&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1000&lt;/span&gt;;
&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; CHECK_INTERVAL_WHEN_SHOWING &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;0.5&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1000&lt;/span&gt;;

&lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; ShowSessionTime &lt;span style=&#34;color:#ff79c6&#34;&gt;extends&lt;/span&gt; React.Component {
    constructor(props) {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;super&lt;/span&gt;(props);
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.state &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {
            timeRemaining&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; MAX_TIME_TO_HIDE_WARNING &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;,
        };
    }

   &lt;span style=&#34;color:#6272a4&#34;&gt;/* Update the remaining time till session timeout */&lt;/span&gt;
    updateRemaining() {
        &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; currentTime &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;Date&lt;/span&gt;.now();
        &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; timeRemaining &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; getCookie(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;serverExpiry&amp;#39;&lt;/span&gt;) &lt;span style=&#34;color:#ff79c6&#34;&gt;-&lt;/span&gt; currentTime;
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.setState({
            timeRemaining,
        });
        &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; timeRemaining;
    }
    componentDidMount() {
        &lt;span style=&#34;color:#6272a4&#34;&gt;// while the modal is open, update every cycle but stop when the time remaining is 0
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;        &lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; whileOpenCheck &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; () =&amp;gt; {
            &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; timeRemaining &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.updateRemaining();
            &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (timeRemaining &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;=&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;0&lt;/span&gt;) {
                setTimeout(whileOpenCheck, CHECK_INTERVAL_WHEN_SHOWING);
            }
        };
        &lt;span style=&#34;color:#6272a4&#34;&gt;// while the modal is closed, update every cycle but switch to the open cycle when we reach the threshold
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;        &lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; whileClosedCheck &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; () =&amp;gt; {
            &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; timeRemaining &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.updateRemaining();
            &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (timeRemaining &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt; MAX_TIME_TO_HIDE_WARNING) {
                setTimeout(whileClosedCheck, CHECK_INTERVAL_WHEN_HIDING);
            } &lt;span style=&#34;color:#ff79c6&#34;&gt;else&lt;/span&gt; {
                setTimeout(whileOpenCheck, CHECK_INTERVAL_WHEN_SHOWING);
            }
        };
        &lt;span style=&#34;color:#6272a4&#34;&gt;// kick off our timeout loop
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;        setTimeout(whileClosedCheck, CHECK_INTERVAL_WHEN_HIDING);
    }

    render() {
        &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; {timeRemaining} &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.state;
        &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; showWarning &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; timeRemaining &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt; MAX_TIME_TO_HIDE_WARNING;
        &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; showWarning &lt;span style=&#34;color:#ff79c6&#34;&gt;?&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;div&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;Time Remaining In Session&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; {timeRemaining} &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;/div&amp;gt; : null;
    }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The &lt;code&gt;componentDidMount&lt;/code&gt; method is the interesting part here.  Notice how the setTimeout based flow has resulted in the flow being reversed?&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;    componentDidMount() {
        &lt;span style=&#34;color:#6272a4&#34;&gt;// THIS PART HAPPENS LAST IF AT ALL
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;        &lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; whileOpenCheck &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; () =&amp;gt; {
            &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; timeRemaining &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.updateRemaining();
            &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (timeRemaining &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;=&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;0&lt;/span&gt;) {
                setTimeout(whileOpenCheck, CHECK_INTERVAL_WHEN_SHOWING);
            }
        };
        &lt;span style=&#34;color:#6272a4&#34;&gt;// THIS IS THE FIRST RECURSIVE LOOP
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;        &lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; whileClosedCheck &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; () =&amp;gt; {
            &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; timeRemaining &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.updateRemaining();
            &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (timeRemaining &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt; MAX_TIME_TO_HIDE_WARNING) {
                setTimeout(whileClosedCheck, CHECK_INTERVAL_WHEN_HIDING);
            } &lt;span style=&#34;color:#ff79c6&#34;&gt;else&lt;/span&gt; {
                setTimeout(whileOpenCheck, CHECK_INTERVAL_WHEN_SHOWING);
            }
        };
        &lt;span style=&#34;color:#6272a4&#34;&gt;// THIS IS THE ENTRY POINT
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;        setTimeout(whileClosedCheck, CHECK_INTERVAL_WHEN_HIDING);
    }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The code is super hard to follow because its defined all out of order.  You have to understand the whole thing before you can wrap your mind around any piece of it, and your eye is going to be wandering back and forth.  Compare that to this reimplementation with async/await:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;    &lt;span style=&#34;color:#ff79c6&#34;&gt;async&lt;/span&gt; checkRemainingAtIntervals() {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;while&lt;/span&gt; (&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.updateRemaining() &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt; MAX_TIME_TO_HIDE_WARNING) {
            &lt;span style=&#34;color:#ff79c6&#34;&gt;await&lt;/span&gt; sleep(CHECK_INTERVAL_WHEN_HIDING);
        }
        &lt;span style=&#34;color:#ff79c6&#34;&gt;while&lt;/span&gt; (&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.updateRemaining() &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;=&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;0&lt;/span&gt;) {
            &lt;span style=&#34;color:#ff79c6&#34;&gt;await&lt;/span&gt; sleep(CHECK_INTERVAL_WHEN_SHOWING);
        }
    }

    componentDidMount() {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.checkRemainingAtIntervals();
    }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We&amp;rsquo;ve pulled the logic out into a separate async function and suddenly everything is so much simpler: we&amp;rsquo;re just using basic loops, with each loop condition updating the remaining time and then checking to see if we should keep looping.  Sleep in this case is just a &lt;a href=&#34;https://benmccormick.org/2015/12/30/es6-patterns-converting-callbacks-to-promises&#34;&gt;promisified&lt;/a&gt; setTimeout:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; sleep &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; millisecs =&amp;gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;Promise&lt;/span&gt;(res =&amp;gt; delay(res, millisecs));
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In fact this version is so much simpler that when I originally wrote the code that this post is based on, I immediately saw a bug that I had missed in the complex version: the time remaining in a session can go up as well as down.  If a user makes a request after I show the warning, the interval will go up and we should re-hide the warning.  But my first few takes both ignored that complexity.  Fortunately it&amp;rsquo;s easy enough to add:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;    &lt;span style=&#34;color:#ff79c6&#34;&gt;async&lt;/span&gt; checkRemainingAtIntervals() {
        &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; remaining &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.updateRemaining();
        &lt;span style=&#34;color:#6272a4&#34;&gt;// keep checking until the session expires
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;        &lt;span style=&#34;color:#ff79c6&#34;&gt;while&lt;/span&gt; (remaining &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;=&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;0&lt;/span&gt;) {
            &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; warningIsShowing &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; remaining &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt; MAX_TIME_TO_HIDE_WARNING;
            &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; interval &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;  warningIsShowing &lt;span style=&#34;color:#ff79c6&#34;&gt;?&lt;/span&gt;
                CHECK_INTERVAL_WHEN_HIDING &lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;
                CHECK_INTERVAL_WHEN_SHOWING;
            &lt;span style=&#34;color:#ff79c6&#34;&gt;await&lt;/span&gt; sleep(interval);
            remaining &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.updateRemaining();
        }
    }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We&amp;rsquo;ve actually gotten even simpler here, with a single loop that runs until the session
expires.  Each time the loop runs, it checks to see whether it should wait for a long or short interval before updating the remaining time again.  Everything happens in ~8 highly readable lines that will be easy to follow for anyone who has used a while loop.&lt;/p&gt;
&lt;p&gt;Compared to our original version we have&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Cut out several &amp;ldquo;intermediary variables&amp;rdquo; that were mostly managing complexity around async, but weren&amp;rsquo;t part of the core problem&lt;/li&gt;
&lt;li&gt;Matched the visual flow to the workflow&lt;/li&gt;
&lt;li&gt;Simplified enough to catch a bug that I missed originally&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I&amp;rsquo;m going to continue to use async-await as the basis for most of my asynchronous code going forward for benefits like this.  If you&amp;rsquo;ve been holding out, browser support has gotten very good and this is a great time to jump in.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Async Await can help readability by matching code structure to the program workflow&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Code that is structured more naturally can be easier to debug and see errors in&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;React&amp;rsquo;s convention of putting render at the bottom of class components has always annoyed me as a result of this.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>Designing Front End Apps For Reliability</title>
      <link>https://benmccormick.org/2019/01/20/190000.html</link>
      <pubDate>Sun, 20 Jan 2019 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2019/01/21/190000.html</guid>
      <description>&lt;p&gt;In my recent &lt;a href=&#34;https://benmccormick.org/2019/01/07/the-concerns-of-fe-architecture/&#34;&gt;post on Front End Architecture&lt;/a&gt; I identified &lt;em&gt;Reliability&lt;/em&gt; as a key concern of front end architecture.  I define reliability as follows:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;An application&amp;rsquo;s ability to provide a consistent functional experience to all users in the intended audience over time.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Let&amp;rsquo;s break that down a bit:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Consistent&lt;/strong&gt; - Reliable applications function the same way over time or degrade gracefully, even on days with heavy load, leap years, and weekends.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Functional&lt;/strong&gt; - Reliable applications allow the users to do the things they need to do, and are forgiving when a user attempts actions that weren&amp;rsquo;t part of an ideal use case.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;All Users In The Intended Audience&lt;/strong&gt; - Reliable applications work for users with strange data who live in different locales, and those with bad network connections and old browsers, at least within the limits of what what the business intends to support.  There is some overlap here with the concept of &lt;strong&gt;accessibility&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Over Time&lt;/strong&gt; - In the real world, no application is ever completely reliable.  Things break down, there are bugs, and new edge cases are discovered.  What we can aspire to though, is an application where things that are working consistently stay working consistently, and as bugs, regressions and edge cases are discovered they get fixed in permanent ways.&lt;/p&gt;
&lt;h3 id=&#34;things-break-down&#34;&gt;Things Break Down&lt;/h3&gt;
&lt;p&gt;So why are applications often unreliable?  There are a fairly predictable set of issues that most applications run into that degrade reliability.&lt;/p&gt;
&lt;h4 id=&#34;unexpected-usage-patterns&#34;&gt;Unexpected Usage Patterns&lt;/h4&gt;
&lt;p&gt;Users are agents of chaos and the real world is stranger than expected.  Your sample database and QA testing doesn&amp;rsquo;t come close to giving you a true idea of how your application will be used.&lt;/p&gt;
&lt;h4 id=&#34;external-failures&#34;&gt;External Failures&lt;/h4&gt;
&lt;p&gt;Google never has bugs right?  Good luck with that.  Even if the rest of the world always wrote perfect software, front end code usually has to deal with the network, even when your user is on a plane, accessing your site over 2G in the mountains, or just dealing with crappy coffeeshop wifi.&lt;/p&gt;
&lt;h4 id=&#34;bugs&#34;&gt;Bugs&lt;/h4&gt;
&lt;p&gt;Bugs happen.  When they happen consistently and repeat themselves, you have a reliability problem.&lt;/p&gt;
&lt;h4 id=&#34;scaling-problems&#34;&gt;Scaling Problems&lt;/h4&gt;
&lt;p&gt;Some things work great on small data sets or with a few users but break down when things get popular.  This isn&amp;rsquo;t just a backend issue.  Data scales as well as people, and your program needs to be robust to slower backend responses when under load.&lt;/p&gt;
&lt;h3 id=&#34;keeping-things-running&#34;&gt;Keeping Things Running&lt;/h3&gt;
&lt;p&gt;I&amp;rsquo;d like to offer some practical strategies for overcoming the challenges I&amp;rsquo;ve listed.  These are things you can consider during code reviews and when setting up your dev processes.&lt;/p&gt;
&lt;h4 id=&#34;1-consider-all-states-and-limit-them-if-you-can&#34;&gt;1. Consider all states, and limit them if you can&lt;/h4&gt;
&lt;p&gt;One of the big leaps in JavaScript based UI development over the past decade has been moving from systems that we modeled as an initial UI state followed by a series of mutations (server generated HTML + jQuery) to systems that were modeled as partially driven with event systems that caused mutations to the UI (Backbone, Angular 1, Knockout), to systems that model the UI as a function of state (React, Vue, Angular2+, Modern Ember) State-driven systems tend to be more robust, because it is often more clear when a particular state might cause a problem, and it is more obvious when a problematic state occurs for a user how it happened.&lt;/p&gt;
&lt;p&gt;Visibility into state is a huge step forward.  The next step is to define the possible states.  You can do this in your head, but it&amp;rsquo;s much easier when using types or by thinking in terms of &lt;a href=&#34;https://benmccormick.org/2018/05/14/mobx-state-machines-and-flags/&#34;&gt;state machines&lt;/a&gt;.  If you can map out different portions of your applications into a limited set of states and define behavior for each of them, reliability will be much easier to achieve.&lt;/p&gt;
&lt;p&gt;The final step is to limit these states where possible.  Some interfaces depend on user input or external data enough that they naturally are effectively &amp;ldquo;infinite state machines&amp;rdquo;, but when you can limit states by cutting scope, rearranging components or cordoning &amp;ldquo;infinite state machines&amp;rdquo; off into a smaller area of your application, you gain a lot of benefits.&lt;/p&gt;
&lt;h4 id=&#34;2-dont-trust-the-network&#34;&gt;2. Don’t trust the network&lt;/h4&gt;
&lt;p&gt;This one is straightforward, and easy to check in code reviews.  Don&amp;rsquo;t assume that anything over a network will return quickly.  Don&amp;rsquo;t assume it will return correctly.  And in fact, don&amp;rsquo;t assume it will return at all.  You may be limited in how you can handle these possibilities, but the baseline competence here is handling them.  Have strategies for loading states, timeouts, error handling and bad formats.  Things like service workers can help here, but also make the problems around the network even more complicated by introducing a new caching layer.  When you start making calls over a network, you&amp;rsquo;re entering the realm of distributed systems and things get tricky fast.  But the least you can do is recognize the complexity and make a plan for it.&lt;/p&gt;
&lt;h4 id=&#34;3-consider-variations-in-data&#34;&gt;3. Consider variations in data&lt;/h4&gt;
&lt;p&gt;Do you have a test data set that you develop against?  Is that your primary source of validation before you send code off into the wild?  Some of that may be unavoidable and out of your control, but remember that users are agents of chaos.  You will encounter data you didn&amp;rsquo;t expect, so plan ahead for challenges.  How would your data visualization function if the dataset you ended up displaying was 2x the size of your test database?  10x? 1000x?  What if the list of products to display in your table contained product names 200 characters long?  Or if some of them were empty?  The real world is strange and you should be ready.&lt;/p&gt;
&lt;h4 id=&#34;4-you-should-have-testing&#34;&gt;4. You should have testing&lt;/h4&gt;
&lt;p&gt;This is another topic that&amp;rsquo;s too big to cover fully here, but basically there&amp;rsquo;s a reason that QA engineers have jobs.  You should have a plan for testing.  That plan will be better if it contains meaningful amounts of automated regression testing, with a clear process for making sure bugs are tested automatically once they&amp;rsquo;ve been discovered and fixed.  If you don&amp;rsquo;t know where to start, always focus on testing the most important things well over testing everything mediocrely. And if you&amp;rsquo;re not in a position to do meaningful automated testing, consider what it will take to get there.&lt;/p&gt;
&lt;h4 id=&#34;5-monitoring&#34;&gt;5. Monitoring&lt;/h4&gt;
&lt;p&gt;Finally, sometimes it&amp;rsquo;s just not possible to catch problems before they ship.  But you can still catch them before too many of your customers do if you put in the work.  I&amp;rsquo;ll be honest, I&amp;rsquo;ve never had a monitoring setup that I&amp;rsquo;ve been happy with at work, but on the front end good monitoring can mean sending console logs over the network so that they&amp;rsquo;re shared with whatever backend logging solution you&amp;rsquo;re using, tracking feature usage through analytics to look for any large problems or lack of usage that may indicate bugs, and even more advanced stuff like session recording in some cases.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Reliability is an application&amp;rsquo;s ability to provide a consistent functional experience to all users in the intended audience over time.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Reliability breaks down due to unexpected usage, external failures, bugs, and scaling problems&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;You can boost reliability by defining and limiting application states, distrusting the network, thinking about variation in data, testing and monitoring&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>6 Keys To Valuable Code Reviews</title>
      <link>https://benmccormick.org/2019/01/13/190000.html</link>
      <pubDate>Sun, 13 Jan 2019 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2019/01/14/190000.html</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve read 2 things lately that really reminded me of the value of code reviews.  One was &lt;a href=&#34;https://amzn.to/2Elk5g8&#34;&gt;A Philosophy Of Software Design&lt;/a&gt; by John Ousterhout, which I reviewed &lt;a href=&#34;https://benmccormick.org/2018/12/31/book-review-philosophy-of-software-design/&#34;&gt;here&lt;/a&gt;.  Philosophy of Software Design is a practical guide to software design, and Ousterhout emphasizes code reviews as the best point for &amp;ldquo;practicing architecture&amp;rdquo; in real world projects.  The 2nd was Sophie Alpert&amp;rsquo;s recent blog post &lt;a href=&#34;https://sophiebits.com/2018/12/25/why-review-code.html&#34;&gt;Why Review Code&lt;/a&gt;, where she lists the various advantages she&amp;rsquo;s seen from having code reviews.  I can&amp;rsquo;t improve on her list, but I can endorse it.  I&amp;rsquo;ve seen all of the things she listed as benefits from code reviews in the past.  However I&amp;rsquo;ve seen these benefits come out in some environments more than others.  So I wanted to share 6 practical tips to getting the most valuable possible out of your team&amp;rsquo;s code reviews.&lt;/p&gt;
&lt;h4 id=&#34;1-make-sure-that-code-reviews-are-multi-directional&#34;&gt;1. Make sure that code reviews are multi-directional&lt;/h4&gt;
&lt;p&gt;When you start doing code reviews, it can be tempting to only have senior developers review code.  After all, they&amp;rsquo;re the ones who know the system best. But not only do you risk burning out your senior staff that way, you also miss out on some of the biggest benefits of code reviews.  You get different benefits with different team combinations.  I&amp;rsquo;m using Junior and Senior here relatively speaking, the roles may change over time or in different areas of the codebase.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Senior Reviewing Junior&lt;/strong&gt; - This is the first thing most folks think about.  This is an opportunity for a more experienced developer to catch bugs in a less experienced developer&amp;rsquo;s code and also give suggestions for improving architecture-level structure, introducing new ways of doing things, or catching when there are opportunities for code consolidation that the original author might not have known about.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Junior Reviewing Senior&lt;/strong&gt; - When a less experienced developer reviews the code of a more experienced developer, its an opportunity for them to see new ways of doing things, and also get &amp;ldquo;cheap&amp;rdquo; exposure to new areas of a codebase.  It&amp;rsquo;s also a great opportunity for them to ask questions about things they don&amp;rsquo;t understand.  But it shouldn&amp;rsquo;t be a one way street.  Often times a fresh pair of eyes are great at catching bugs, and if a code review is particularly confusing to a less experienced dev, it&amp;rsquo;s a sign that the code may need to be rewritten or better documented so that it can be maintained in the future.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Peer Reviewing Peer&lt;/strong&gt; - When 2 developers have roughly equal skill and experience with the codebase, code reviews are still an opportunity for a second pair of eyes, but they also have the benefits of building team collective knowledge about the codebase and exposing times when there are differences in approach across the team.  Conversations at this level are a great place to standardize on best practices and team conventions.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;2-hold-reviewers-responsible-for-the-code-they-review&#34;&gt;2. Hold reviewers responsible for the code they review&lt;/h4&gt;
&lt;p&gt;If a bug makes it past initial development efforts and is caught by QA or ends up in production, who is responsible for it?  Although there will ideally always be layers of accountability here, most developers I know naturally tend to hold themselves responsible when code they wrote breaks something, but also apply the same standard to others.  This can lead to rubber-stamp code reviews when things get busy, since there&amp;rsquo;s no &amp;ldquo;skin in the game&amp;rdquo;.  The benefits of code review tend to come out though, when developers take that same responsibility for the code they review.  A team culture that sees the reviewer and the developer as equally responsible for maintainable code, bug-smashing, and other architecture concerns will lead to better code reviews.  This means treating code review as a core job responsibilities for devs and rewarding those who do it well, rather than just tacking it on.&lt;/p&gt;
&lt;h4 id=&#34;3-match-technology-to-your-process&#34;&gt;3. Match technology to your process&lt;/h4&gt;
&lt;p&gt;The teams I&amp;rsquo;ve worked on that didn&amp;rsquo;t have real code review processes also didn&amp;rsquo;t have an easy setup to make it work.  They were reviewing diffs manually in their editors or over email.  Tools like Github, Bitbucket and Gitlab have made this much easier.  If you want this to be part of your process, make it as easy as possible.&lt;/p&gt;
&lt;h4 id=&#34;4-use-checklists-where-appropriate&#34;&gt;4. Use checklists where appropriate&lt;/h4&gt;
&lt;p&gt;In moderation, I&amp;rsquo;ve found checklists a useful tool for code reviews.  If your team has specific areas of focus that you want to improve compliance on, it can be helpful to give reviewers a list of items to sign off on.  For instance:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Verify change supports internationalization&lt;/li&gt;
&lt;li&gt;Verify change doesn&amp;rsquo;t add any new code with legacy framework&lt;/li&gt;
&lt;li&gt;If change is user-facing, verify it includes documentation updates&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can take this too far, the review process shouldn&amp;rsquo;t be reduced to repetitive box-ticking.  But these can be great as guides for implementing new initiatives or addressing problem areas in code.&lt;/p&gt;
&lt;h4 id=&#34;5-make-code-reviews-as-atomic-as-possible&#34;&gt;5. Make code reviews as atomic as possible&lt;/h4&gt;
&lt;blockquote class=&#34;twitter-tweet&#34; data-lang=&#34;en&#34;&gt;&lt;p lang=&#34;en&#34; dir=&#34;ltr&#34;&gt;10 lines of code = 10 issues.&lt;br&gt;&lt;br&gt;500 lines of code = &amp;quot;looks fine.&amp;quot;&lt;br&gt;&lt;br&gt;Code reviews.&lt;/p&gt;&amp;mdash; I Am Devloper (@iamdevloper) &lt;a href=&#34;https://twitter.com/iamdevloper/status/397664295875805184?ref_src=twsrc%5Etfw&#34;&gt;November 5, 2013&lt;/a&gt;&lt;/blockquote&gt;
&lt;p&gt;Huge code reviews are overwhelming, and much easier to rubber stamp.  When you develop a culture of creating small focused issues and reviewing each of them, it leads to more interaction and better results. Single issue (atomic) code reviews are best.  As a rule of thumb, if you can describe the change without using the words &amp;ldquo;and&amp;rdquo;, &amp;ldquo;rewrite&amp;rdquo;, or &amp;ldquo;a couple of different&amp;rdquo;, you&amp;rsquo;re probably doing alright.&lt;/p&gt;
&lt;h4 id=&#34;6-leave-space-to-make-changes&#34;&gt;6. Leave space to make changes&lt;/h4&gt;
&lt;p&gt;Finally, code reviews will have the most value if as a team you&amp;rsquo;re committed to acting on the feedback received.  That means being supportive when a code review leads to a re-write or refactor.  Sometimes that will need to be delayed of course, but in a healthy process there should usually be time to act on feedback.  This is of course easier if you&amp;rsquo;ve followed the previous suggestion and kept your code reviews small.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>What&#39;s involved in Front End Architecture?</title>
      <link>https://benmccormick.org/2019/01/06/190000.html</link>
      <pubDate>Sun, 06 Jan 2019 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2019/01/07/190000.html</guid>
      <description>&lt;p&gt;The word &amp;ldquo;architecture&amp;rdquo; gets thrown around a lot in software discussions.  But we don&amp;rsquo;t seem to always use it the same way.  Some example usages:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Our app uses Redux for our architecture.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Sometimes we assume that because we are using a framework or data management library, that must be our architecture.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I created a diagram of our dependency graph, showing all the imports in the code, as a way of seeing our architecture.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;We could also say the way your program is structured (which files depend on which other files) represents your architecture.  If we&amp;rsquo;re fancy, then maybe we have &lt;a href=&#34;https://en.wikipedia.org/wiki/Unified_Modeling_Language&#34;&gt;UML diagrams&lt;/a&gt; representing this structure.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Bob is our architecture guy: he decides what dependencies we can bring in, is always asking us to refactor code to make it &amp;ldquo;cleaner&amp;rdquo;, and runs a design meeting before each feature to decide how to structure the code&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This final quote sounds like architecture is more about the decisions you&amp;rsquo;re making as you go through a project.&lt;/p&gt;
&lt;h3 id=&#34;appealing-to-authority&#34;&gt;Appealing to authority?&lt;/h3&gt;
&lt;p&gt;So if the community isn&amp;rsquo;t using the term consistently, let&amp;rsquo;s ask the experts.  Here are 2 definitions from folks who have written popular books on software architecture.&lt;/p&gt;
&lt;p&gt;Robert Martin (Uncle Bob) uses the following definition in &lt;a href=&#34;https://amzn.to/2rROcEA&#34;&gt;Clean Architecture&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The goal of software architecture is to minimize the human resources required to build and maintain the required system.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Martin Fowler gave his definition in a talk titled &lt;a href=&#34;https://www.youtube.com/watch?v=DngAZyWMGR0&#34;&gt;Making Architecture Matter&lt;/a&gt;. It is worth watching in full, but paraphrased, his definition is:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Software architecture is those decisions which are both important and hard to change&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;These 2 definitions turn out to be complementary.  Uncle Bob motivates architecture: we&amp;rsquo;re focused on minimizing the work put into the system.  Martin Fowler&amp;rsquo;s definition shows what parts of the system architecture is concerned with: the parts that are &amp;ldquo;important&amp;rdquo; and hard to change.&lt;/p&gt;
&lt;p&gt;The next question of course is&amp;hellip; what is important?  The unsatisfactory answer is that it depends.  It will change between projects, and will change within a project over time.  But when we scope the question to the domain of front end development, common themes emerge.  Specifically there are 6 areas of concern that I see coming up again and again in public and private front end architecture discussions.  They&amp;rsquo;re not exclusive to the front end, but they&amp;rsquo;re a good starting point for anyone thinking about building web applications.&lt;/p&gt;
&lt;h4 id=&#34;ease-of-change&#34;&gt;Ease of Change&lt;/h4&gt;
&lt;p&gt;When new requirements arrive, how quickly are developers able to make changes and release new code to production?  When there are bugs, how easy is it to find the problem and fix it?  Are developers able to consistently deliver correct code?  Or are multiple iterations often required?&lt;/p&gt;
&lt;h4 id=&#34;security&#34;&gt;Security&lt;/h4&gt;
&lt;p&gt;Can a malicious user inject code into your site?  Are you unnecessarily exposing information about your users or code structure? And you are working with your API developers to use secure authentication and authorization practices right?&lt;/p&gt;
&lt;h4 id=&#34;accessibility&#34;&gt;Accessibility&lt;/h4&gt;
&lt;p&gt;This concern is broader than the way the word is often used in web dev circles.  Is the full audience of this site or application able to use it with as few limitations as possible?  Users with disabilities?  Users with older but supported browsers?  How about international users or those with slow connections?  Does your site work on mobile?  Offline?  On Apple Watch?  Do you support AMP? And do your pages appear nicely on social media?  Do you even care about any of these audiences? Maybe you&amp;rsquo;re optimizing for people who aren&amp;rsquo;t your users?&lt;/p&gt;
&lt;h4 id=&#34;reliability&#34;&gt;Reliability&lt;/h4&gt;
&lt;p&gt;Is a site or  application consistently available to users?  Does it often fail, and if so how does it recover?  If things are breaking, are the developers aware of it quickly?  Do different users in different scenarios receive a consistent experience?&lt;/p&gt;
&lt;h4 id=&#34;performance&#34;&gt;Performance&lt;/h4&gt;
&lt;p&gt;Is a site or application consistently quick to load and interact with?  If there are animations or highly interactive elements, are they responsive and usable, or do they freeze/jank? Is the user disrupted in their tasks by strange loading behavior?&lt;/p&gt;
&lt;h4 id=&#34;capability&#34;&gt;Capability&lt;/h4&gt;
&lt;p&gt;Is your site limited in fulfilling its purpose because of foundational decisions or tradeoffs with the other concerns?  Have you made decisions that let you serve your audience in unique ways because of your tech stack or development processes?  Do your technical decisions even make sense in the context of your site or application&amp;rsquo;s purpose?&lt;/p&gt;
&lt;h3 id=&#34;coming-soon&#34;&gt;Coming Soon&lt;/h3&gt;
&lt;p&gt;I&amp;rsquo;m hoping to look at each of these areas more in depth in the coming weeks, as well as exploring how we make decisions that impact multiple areas simultaneously.  In the meantime, as you&amp;rsquo;re looking at decisions and tools that will impact the long term structure of your front end application, consider how they&amp;rsquo;ll impact each of these areas.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Architecture is about decisions that are important and hard to change, with a goal of improving the efficiency of a project&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Front End architecture is often concerned with the areas of Ease of Change, Security, Accessibility, Reliability, Performance and Capability&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Book Review: Radical Candor</title>
      <link>https://benmccormick.org/2018/12/31/190000.html</link>
      <pubDate>Mon, 31 Dec 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2019/01/01/190000.html</guid>
      <description>&lt;p&gt;Have you ever read a non-fiction book that you just couldn&amp;rsquo;t put down because you kept hitting paragraph after paragraph of useful, practical wisdom?  That was me reading &lt;a href=&#34;https://amzn.to/2SABeXz&#34;&gt;Radical Candor&lt;/a&gt; by Kim Scott this summer.  It&amp;rsquo;s a ~200 page masterpiece on communication, leadership and being real at work.  The ideas in Radical Candor have already been a huge help to me as I&amp;rsquo;ve transitioned into a manager role over the past few months, and I fully expect to refer back to them a lot in the years to come.  It was the best thing I read in 2018, so I wanted to write a quick review to start the new year.&lt;/p&gt;
&lt;p&gt;Radical Candor is split into 2 parts: part 1 is philosophical, and builds out a philosophy of working with and managing people that&amp;rsquo;s based on honest guidance and feedback backed by genuine care.  The second half of the book is tactical and focused on techniques that managers can use to implement the philosophical ideas.  Overall it is a book for managers, but is also relevant and useful for anyone who has a manager or who wants to work better with others in a professional setting.&lt;/p&gt;
&lt;div class=&#34;inline-img&#34;&gt;
    &lt;img alt=&#34;Radical Candor diagram&#34; src=&#34;candor-diagram.png&#34;/&gt;
&lt;/div&gt;
&lt;p&gt;The heart of the book is the 2x2 grid diagram that Scott sprinkles throughout the chapters, showing the 4 quadrants that can characterize an interaction, relationship or communication style.  People who don&amp;rsquo;t care about those they work with and also don&amp;rsquo;t challenge them fall into manipulative insincerity and should be avoided at all costs.  The Steve Jobsian category of Obnoxious Aggression is when somebody is willing to challenge directly but doesn&amp;rsquo;t care about the people they&amp;rsquo;re challengin. To Scott&amp;rsquo;s mind, Obnoxious Aggression is preferred over Ruinous Empathy; when people who hate the idea of hurting somebody so much that they fail to tell them important truths.  But the target quadrant is Radical Candor, a state where you deal with people in a way that is backed by real humanity while still being willing to be exceptionally honest and challenging.&lt;/p&gt;
&lt;p&gt;This core idea wasn&amp;rsquo;t super new to me, I had seen it formulated in Church contexts as &lt;code&gt;Grace + Truth = Growth&lt;/code&gt; in the past.  But Scott puts in the work to show how these ideas play out in a wide variety of professional situations and relationships, and her examples left me teeming with new ideas on how to interact better with my coworkers.  The theme is good, but the implementation ideas and little nuggets of wisdom and experience sprinkled throughout are better.  As a result, Radical Candor is one of the best books on relationship and communication I have ever read.&lt;/p&gt;
&lt;p&gt;I would recommend it for anyone who&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Manages people&lt;/li&gt;
&lt;li&gt;Wants to manage people&lt;/li&gt;
&lt;li&gt;Has a manager&lt;/li&gt;
&lt;li&gt;Has to deal with people&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Do yourself a favor and check it out.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Book Review: A Philosophy of Software Design</title>
      <link>https://benmccormick.org/2018/12/30/190000.html</link>
      <pubDate>Sun, 30 Dec 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/12/31/190000.html</guid>
      <description>&lt;p&gt;A lot of the software books out there these days are marching towards their expiration dates the day they&amp;rsquo;re written.  When I see titles like &amp;ldquo;Angular 2 Development&amp;rdquo;, &amp;ldquo;Learning JavaScript with React&amp;rdquo;, &amp;ldquo;Writing Native Apps with Ionic 2 and Lodash 4&amp;rdquo; I know that the book will soon have out of date code examples and will not contain the latest ways a community is using the libraries they&amp;rsquo;re discussing.  There is value in these types of books and they often represent a monumental amount of thought and time from their authors, but 5 years from now they will no longer be relevant.  I love reading books that I know will last.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://amzn.to/2Rpu6zX&#34;&gt;A Philosophy Of Software Design&lt;/a&gt; by &lt;a href=&#34;https://en.wikipedia.org/wiki/John_Ousterhout&#34;&gt;John Ousterhout&lt;/a&gt; is a book that will last.  It&amp;rsquo;s full of timeless software writing advice that isn&amp;rsquo;t tied to a particular language, library or point of time.  Although not formally organized this way, it seems to be divided into ~4 parts: 2 chapters on the idea of complexity, a concept which Ousterhout uses as the unifying theme of the book, 8 chapters on what I&amp;rsquo;d describe as the structural design of software systems, 7 chapters on more &amp;ldquo;code level concerns&amp;rdquo; like naming conventions, comments and making code obvious, and then a final 2 chapters that feel a bit more like appendixes which discuss some common software trends and designing for performance.&lt;/p&gt;
&lt;p&gt;The best part of the book is those first few chapters where Ousterhout eloquently describes the problems that complexity can cause in a software project and lays out the distinction between a tactical and strategic approach to coding.  This is the heart of the titular &lt;strong&gt;philosophy&lt;/strong&gt; of Software Design: the idea that software engineering is ultimately a fight against complexity.  It&amp;rsquo;s a strong vision clearly articulated.&lt;/p&gt;
&lt;p&gt;The &amp;ldquo;structural&amp;rdquo; sections of the book are all sound in an opinionated way.  The book makes an argument for larger implementations hidden behind smaller abstractions, which Ousterhout calls &amp;ldquo;deep modules&amp;rdquo;, and much of the structural section is through that lens.  This isn&amp;rsquo;t as open-minded as architecture advice I&amp;rsquo;ve seen elsewhere, but the benefit is that it&amp;rsquo;s prescriptiveness makes it much easier to use as a guide or code review tool than more situational or caveated advice.  That practical aspect is clearly a goal of the book, and the approach therefore makes sense.&lt;/p&gt;
&lt;p&gt;After chapter 11, the book takes a sudden detour from higher level concepts into much more concrete realms.  There is an extensive treatment of commenting style, naming conventions and other ways to make code readable and obvious.  There is a coherent through-line of building maintainable systems throughout, but the transition felt strange.  The content is still good though.&lt;/p&gt;
&lt;p&gt;The book ends on a chapter addressing modern software trends through the lens of the concepts considered in the book, which felt like a good place to wrap up, and then a chapter on designing for performance.  Given the books focus on complexity and the size of the performance topic, this chapter is content to argue that simple designs are friendly to performance, without trying to unpack many performance related topics.  It felt a bit tacked on to me, but it makes sense as a piece of objection handling for those who feel that they can&amp;rsquo;t simplify their architecture for performance reasons.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;A Philosophy of Software Design&lt;/em&gt; is going to be my new go to recommendation for developers who are able to write code that runs but want to start thinking about how to write better code.  It doesn&amp;rsquo;t have the depth of something like &lt;a href=&#34;https://benmccormick.org/2018/02/14/book-review-clean-architecture/&#34;&gt;Clean Architecture&lt;/a&gt;, but it is extremely readable and approachable, and I&amp;rsquo;ve never seen an architecture-level book that was so focused on actionable advice.  If you take the advice in the first chapter and consult the book during code reviews, every chapter in the book has something to consider when looking at a piece of non-trivial code.  That makes it a perfect introduction to higher-level software design thinking.  If you think that would be a fit for you, &lt;a href=&#34;https://amzn.to/2Rpu6zX&#34;&gt;go ahead and check it out&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Want to work with me?</title>
      <link>https://benmccormick.org/2018/11/02/190000.html</link>
      <pubDate>Fri, 02 Nov 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/11/03/190000.html</guid>
      <description>&lt;p&gt;Hey all.  The blog is still &lt;a href=&#34;https://benmccormick.org/2018/10/13/pressing-pause/&#34;&gt;on pause&lt;/a&gt;, but I wanted to take a moment to share that I&amp;rsquo;m hiring for my team at &lt;a href=&#34;https://www.whatcounts.com/&#34;&gt;Whatcounts&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This is a mid-level position focused on coming in and helping me build a new React-based UI for an older Java based SaaS application.  You&amp;rsquo;ll get to work with modern React/JavaScript code and help shape the project&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.  I&amp;rsquo;m looking for folks who are comfortable building out complex pages quickly and are knowledgeable about JavaScript, ideally you&amp;rsquo;re at least starting to get comfortable with &lt;a href=&#34;https://benmccormick.org/2017/07/19/ten-things-javascript/&#34;&gt;these 10 concepts&lt;/a&gt; and you want to keep growing as a developer.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m hiring both in Atlanta GA and Durham NC&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;, so if you&amp;rsquo;re located there and think you&amp;rsquo;d be a fit feel free to &lt;a href=&#34;https://www.linkedin.com/jobs/view/942692404/&#34;&gt;apply on Linkedin&lt;/a&gt; or reach out to me directly.&lt;/p&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;I&amp;rsquo;m actively considering pulling in some other cool tech like Typescript and Storybook, and the person who fills this role will have the opportunity to help make some of those decisions.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;No remote at this time, sorry folks, although there will be considerable flexibility to work from home a few times a week.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>Pressing Pause</title>
      <link>https://benmccormick.org/2018/10/12/190000.html</link>
      <pubDate>Fri, 12 Oct 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/10/13/190000.html</guid>
      <description>&lt;p&gt;Due to a plethora of life events happening this year, I&amp;rsquo;m going to be putting the blog on pause for a while.  So no more updates through the end of the year.  Will re-evaluate then and hopefully start things back up.  I have plans to take the weekly links stuff I&amp;rsquo;ve been doing the past year and turn it into a real email newsletter with a better template, and some exciting ideas for a new blog series.  But I lack the capacity to follow up on them for now.  So Happy Holidays in advance everybody, I hope to be back early next year.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Weekly Links: September 30</title>
      <link>https://benmccormick.org/2018/09/29/weekly-links-september.html</link>
      <pubDate>Sat, 29 Sep 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/09/30/weekly-links-september.html</guid>
      <description>&lt;h3 id=&#34;javascript--the-web&#34;&gt;Javascript &amp;amp; the Web&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://hackernoon.com/principles-of-component-api-prop-design-bb20cd58da54&#34;&gt;Principles of Component API Design | Chris Schmitz&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Good advice for designing React components&lt;/p&gt;
&lt;h3 id=&#34;programming-tools&#34;&gt;Programming Tools&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://www.sublimemerge.com/&#34;&gt;Sublime Merge&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A new Git tool from the makers of Sublime Text.  Looks lightning fast, good looking and usable.  Exactly what you&amp;rsquo;d expect.  I&amp;rsquo;m not a big UI guy for Git, but I&amp;rsquo;ll be playing with this, and it might be my new go-to recommendation.&lt;/p&gt;
&lt;h3 id=&#34;book-review&#34;&gt;Book Review&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://amzn.to/2OqjY8u&#34;&gt;The Everything Store | Brad Stone&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Still finishing this one up, but can already recommend it.  A great look into the creation of one of the most important companies in the world.  I was pretty interested to read about how intense Jeff Bezos is, and how hard he ran the early employees of Amazon.  I hadn&amp;rsquo;t realized that he fell into the Steve Job&amp;rsquo;s school of CEO-hood.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Weekly Links: September 23</title>
      <link>https://benmccormick.org/2018/09/22/weekly-links-september.html</link>
      <pubDate>Sat, 22 Sep 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/09/23/weekly-links-september.html</guid>
      <description>&lt;h3 id=&#34;javascript--the-web&#34;&gt;Javascript &amp;amp; the Web&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://www.netlify.com/blog/2018/09/12/the-rise-of-immer-in-react/&#34;&gt;The Rise of Immer | Shawn Wang&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m a few weeks late on this one, but it is worth your time.  Shawn breaks down a new trend in React state management: the increasing popularity of Immer as a base for improving state management APIs.  I&amp;rsquo;m particularly interested in &lt;a href=&#34;https://github.com/aweary/react-copy-write&#34;&gt;react-copy-write&lt;/a&gt; as a new simpler paradigm for React state management.  Right now Redux has &amp;ldquo;won&amp;rdquo; that space, and MobX is the clear second option, but it still feels like there&amp;rsquo;s room for improvement and new options.  Will be cool to see what people build on top of immer.&lt;/p&gt;
&lt;h3 id=&#34;leadership&#34;&gt;Leadership&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.usejournal.com/how-to-fail-as-a-new-engineering-manager-30b5fb617a&#34;&gt;How to fail as a new engineering manager | Brad Armstrong&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;As a new engineering manager, I found this list super helpful.  I can already feel the temptation to fall into many of these traps, and it&amp;rsquo;s encouraging to hear about them from somebody who has gone ahead of me.&lt;/p&gt;
&lt;h3 id=&#34;book-review&#34;&gt;Book Review&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://amzn.to/2xzyhho&#34;&gt;Every Good Endeavor | Tim Keller&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This is a &amp;ldquo;Christian book&amp;rdquo;, but I think it would be interesting to anyone who is interested in thinking about why we work, and how we find meaning in our work.  If you are a Christian, there&amp;rsquo;s lots of insight here connecting the truths of our faith to the rhythms of our work lives.  If you&amp;rsquo;re not, there is plenty to provoke thought, because the questions this book raises; why do we work? why is work often so unfulfilling? How do we find our purpose?; are universal questions regardless of whether you agree with Keller&amp;rsquo;s answers or foundational beliefs.  Highly recommended.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Weekly Links: September 16</title>
      <link>https://benmccormick.org/2018/09/15/weekly-links-september.html</link>
      <pubDate>Sat, 15 Sep 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/09/16/weekly-links-september.html</guid>
      <description>&lt;h3 id=&#34;javascript--the-web&#34;&gt;Javascript &amp;amp; the Web&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://medium.freecodecamp.org/the-12-things-you-need-to-consider-when-evaluating-any-new-javascript-library-3908c4ed3f49&#34;&gt;The 12 Things You Need to Consider When Evaluating Any New JavaScript Library | Sacha Greif&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This is a smart set of criteria to consider when looking at new tools.  I&amp;rsquo;d add that it&amp;rsquo;s always worth comparing a library to a &amp;ldquo;do it without the library&amp;rdquo; approach, to make sure you understand the benefits that you&amp;rsquo;re getting for your specific project.&lt;/p&gt;
&lt;h3 id=&#34;leadership&#34;&gt;Leadership&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://us2.campaign-archive.com/home/?u=1f50ce22f02ed0ffc80c10aff&amp;amp;id=8c0f947e69&#34;&gt;Newsletter | Lara Hogan&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve already linked several of &lt;a href=&#34;https://larahogan.me/&#34;&gt;Lara Hogan&amp;rsquo;s&lt;/a&gt; blog posts in this space, and now she&amp;rsquo;s started an email newsletter.  Worth checking out.&lt;/p&gt;
&lt;h3 id=&#34;book-review&#34;&gt;Book Review&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://amzn.to/2xfflEi&#34;&gt;Ready Player One | Ernest Cline&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m about 7 years late on this (and even 6 months late for the movie hype), but Ready Player one was a great little sci-fi novel that uses 80&amp;rsquo;s pop culture as a background for a bunch of insightful commentary about our modern tech culture and where it may be heading.  A lot of fun, and worth reading if you&amp;rsquo;ve missed it for this long like me.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Weekly Links: September 7</title>
      <link>https://benmccormick.org/2018/09/06/weekly-links-september.html</link>
      <pubDate>Thu, 06 Sep 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/09/07/weekly-links-september.html</guid>
      <description>&lt;h3 id=&#34;javascript-and-the-web&#34;&gt;JavaScript And The Web&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://stateofjs.com/&#34;&gt;State of JS Survey | Raphaël Benitte, Sacha Greif &amp;amp; Michael Rambeau&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This survey is always a great look into the JavaScript community, and it just opened for this year.  If you&amp;rsquo;re reading this, please fill it out.  I&amp;rsquo;ll look forward to seeing what they&amp;rsquo;ve learned in a few months.&lt;/p&gt;
&lt;h3 id=&#34;books-for-programmers&#34;&gt;Books For Programmers&lt;/h3&gt;
&lt;p&gt;It&amp;rsquo;s a bit of a slow week links wise, so this week I want to share some of my favorite &amp;ldquo;timeless&amp;rdquo; programming books.  These are books that will still be relevant in 10 years.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://amzn.to/2wVjXyi&#34;&gt;The Pragmatic Programmer | Andy Hunt &amp;amp; David Thomas&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;My favorite book on general programming &amp;ldquo;tactics&amp;rdquo;.  Lots of code level tips and tricks here, as well as some higher level architecture thinking.  Some of the specific examples have aged out, but the general concepts discussed in this book are timeless.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://amzn.to/2mKoejo&#34;&gt;Clean Architecture | Robert Martin&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I reviewed this one &lt;a href=&#34;https://benmccormick.org/2018/02/14/book-review-clean-architecture/&#34;&gt;earlier this year&lt;/a&gt;, and it&amp;rsquo;s a relatively new book, but I&amp;rsquo;m confident that it is built to last.  This is a great book on programming &amp;ldquo;strategy&amp;rdquo;, the high level construction of maintainable programs.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://amzn.to/2NpJyK7&#34;&gt;How To Win Friends And Influence People | Dale Carnegie&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Not a programming book, but for most programmers who have achieved a minimal level of technical proficiency, the best thing they can do to get better in their career is not more technical growth, but instead growth on their &amp;ldquo;soft&amp;rdquo; skills.  Communicating complex topics, helping teams work well together, working through interpersonal issues, negotiation and persuasion are all huge skills for professional software developers.&lt;/p&gt;
&lt;p&gt;There are lots of &amp;ldquo;business&amp;rdquo; books out there that are worthwhile, but this is the best book I&amp;rsquo;ve ever read on the simple yet endlessly deep topic of relating to our fellow human beings.  It has been relevant and helpful for 82 years, and I wouldn&amp;rsquo;t expect that to change soon.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Weekly Links: September 1</title>
      <link>https://benmccormick.org/2018/08/31/weekly-links-september.html</link>
      <pubDate>Fri, 31 Aug 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/09/01/weekly-links-september.html</guid>
      <description>&lt;h3 id=&#34;javascript-and-the-web&#34;&gt;JavaScript And The Web&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.angularindepth.com/practical-application-of-reverse-engineering-guidelines-and-principles-784c004bb657&#34;&gt;Reverse Engineering React | Angular In Depth&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A really cool look at how you can approach a new code base and start learning how it works quickly&lt;/p&gt;
&lt;h3 id=&#34;programming-tools&#34;&gt;Programming Tools&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://pybowler.io&#34;&gt;Bowler | Facebook Open Source&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This looks like &amp;ldquo;JSCOdeshift for Python&amp;rdquo; to me: a way to quickly update codebases to use new patterns and practices.  I love it. You can &lt;a href=&#34;https://benmccormick.org/2018/06/18/codemod-survival/&#34;&gt;check out my experience using JavaScript Codemods here&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/sharkdp/bat&#34;&gt;bat&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;bat is a prettier &lt;a href=&#34;https://en.wikipedia.org/wiki/Cat_(Unix)&#34;&gt;cat&lt;/a&gt;:  dump a file into the terminal, but use syntax highlighting and line numbers.  Good stuff for anyone who lives on the command line.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Weekly Links: August 18th</title>
      <link>https://benmccormick.org/2018/08/17/weekly-links-august.html</link>
      <pubDate>Fri, 17 Aug 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/08/18/weekly-links-august.html</guid>
      <description>&lt;h3 id=&#34;javascript-and-the-web&#34;&gt;JavaScript and the Web&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://ethanmarcotte.com/wrote/bits/&#34;&gt;Bits | Ethan Marcotte&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ll pretty much always link performance posts that do a good job laying out the challenges in a way that respects both the technical and business POV.  Ethan advocates here for a more structural view to performance problems on the web and wonders how we can find more performant ways to solve businesses revenue problems.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://egghead.io/browse/frameworks/react&#34;&gt;React Community Resources | Egghead&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Egghead has accumulated a pretty amazing set of beginner React resources that are free for non-members.  If you&amp;rsquo;re trying to get into React, this is a pretty good place to start.&lt;/p&gt;
&lt;h3 id=&#34;books&#34;&gt;Books&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://amzn.to/2vX6yGo&#34;&gt;Radical Candor | Kim Scott&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I may write this up as a full review later, but Radical Candor was the best book I&amp;rsquo;ve read this year.  It&amp;rsquo;s a book for managers, but it really was just one of the best books I&amp;rsquo;ve ever read on communication and relationships.  If you want to work better with others, Radical Candor is worth buying.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Weekly Links: August 5th</title>
      <link>https://benmccormick.org/2018/08/04/weekly-links-august.html</link>
      <pubDate>Sat, 04 Aug 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/08/05/weekly-links-august.html</guid>
      <description>&lt;h3 id=&#34;javascript-and-the-web&#34;&gt;JavaScript and the Web&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://medium.com/@addyosmani/the-cost-of-javascript-in-2018-7d8950fbb5d4&#34;&gt;The Cost Of JavaScript in 2018 | Addy Osmani&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This was a great breakdown of how exactly large JavaScript bundles cause sites to be slow and how that impacts business needs.  These type of advocacy pieces have a tendency to clump all businesses together a bit too much&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;, but Addy is pretty reasonable about that and it&amp;rsquo;s important for every front end dev to understand these tradeoffs and problems, even if they don&amp;rsquo;t need to make them top priority for every project.&lt;/p&gt;
&lt;h3 id=&#34;programming-tools&#34;&gt;Programming Tools&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://css-tricks.com/on-switching-code-editors/&#34;&gt;On Switching Code Editors | Chris Coyier&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m in the middle of possibly switching to VSCode from Atom, which I switched to from Vim, which I switched to from Sublime Text, which originally introduced me to a world beyond overweight IDEs like Eclipse.  So I can relate to this article, and it&amp;rsquo;s a great framework for thinking through switches.  I will say, I don&amp;rsquo;t necessarily think I&amp;rsquo;ve made the best choices here.  I&amp;rsquo;m not sure that since I&amp;rsquo;ve learned Vim keybindings, any of my switches have actually increased my productivity.  There&amp;rsquo;s a cost to learning new tools, even when they have shiny new stuff. &lt;em&gt;grumbles a bit and then goes back to chasing the shiny&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.prototypr.io/people-are-going-crazy-over-framer-x-9576448daa18&#34;&gt;People Are Going Crazy Over Framer X | Aaron Adler&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;My twitter feed was blowing up with people talking about Framer X this week, a tool for designers to build interactive designs/prototypes based on React.  This post is a little old but was the best summary of the concept I could find.  Framer X is still in a private beta, so it will be interesting to see what happens when it goes public.&lt;/p&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;Even in 2018, not everyone is serving 3rd world businesses or gets a large chunk of their traffic from mobile.  And performance always needs to be traded off against other business goals.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>Feedback Loops</title>
      <link>https://benmccormick.org/2018/08/01/190000.html</link>
      <pubDate>Wed, 01 Aug 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/08/02/190000.html</guid>
      <description>&lt;p&gt;&lt;em&gt;How do we get better faster?&lt;/em&gt;  It&amp;rsquo;s amazing to consider the amount of money, thought and effort that has gone into solving that one simple problem in software development over the past 2 decades.  Here&amp;rsquo;s a small sample of buzzwords, trends and methodology that are concerned with reducing the time between making a change to software and seeing the results:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Agile -&lt;/strong&gt; Agile is all about delivering working software sooner, so that you produce value faster and learn lessons quickly.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Test Driven Development (TDD) -&lt;/strong&gt; Test driven development is a process designed to let you know as soon as possible when a change has had the desired effect during development, and also sets up the conditions under which you know as soon as possible when a change has had an undesirable side effect.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Devops -&lt;/strong&gt; Devops has been a push over the past decade to automate and control all parts of the software creation, deployment and maintenance life cycle.  Automation like continuous integration servers that run your test after every commit, chat bots that alert you based on site performance metrics, and servers that automatically build a copy of every branch for testing in a virtual machine are all examples of Devops being used to speed up the point when you know that a change worked or didn&amp;rsquo;t work.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Developer Experience -&lt;/strong&gt; This is a more recent buzzword that I&amp;rsquo;ve seen thrown around a lot in the JavaScript community, talking about improving developer tools.  Developer tool features like hot reloading, nicer error messages, specialized debugging and profiling tools, and fast build times all fight this same problem of getting a result as fast as possible.&lt;/p&gt;
&lt;h3 id=&#34;feedback-loops&#34;&gt;Feedback Loops&lt;/h3&gt;
&lt;p&gt;All of these tools are concerned with &lt;em&gt;feedback loops&lt;/em&gt;, the process by which developers, designers and product managers make changes, learn about the effect of those changes, and then iterate.  Teams with slow feedback loops spend a lot of time planning and thinking about every change, making sure to get everything right. They feel the cost distinctly each time they make a mistake, and it generally leads to a more cautious mindset.  Teams with fast feedback loops can plan too.  But they also have the option of taking a more experimental attitude and learning from their attempts. This can happen at multiple scales:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;developer&lt;/strong&gt; can try out 5 different CSS rules in the UI in a few seconds if his UI is hot reloading and he doesn&amp;rsquo;t have to wait for a whole SCSS bundle to recompile&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;QA team&lt;/strong&gt; can immediately know if somebody pushes a change that would breaks tests if they have a CI server set up to run tests against every new commit to each branch.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;product team&lt;/strong&gt; can see quickly that a new feature is problematic if he&amp;rsquo;s able to see detailed analytics on usage, instead of waiting to do enough user interviews to get a full picture&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;company&lt;/strong&gt; can change direction if they ship an MVP early instead of attempting to wait and release the perfect product&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;closing-your-loops&#34;&gt;Closing Your Loops&lt;/h3&gt;
&lt;p&gt;As a developer who wants to make your product better, one of your best power moves is finding ways to speed up feedback loops.  Here are 4 suggestions for how to do that:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Ask Questions Early:&lt;/strong&gt; One of the most important feedback loops for a developer is between yourself and the individual in charge of defining what you&amp;rsquo;re building.  If you simply take requirements from your PM/Manager/Lead/Designer/CEO/Client and go off and build your giant amazing piece of beautiful software, without any clarification, there&amp;rsquo;s a pretty good chance you&amp;rsquo;re going to get to build it again, this time twice as fast without the budget.  Asking clarifying questions early prevents you wasting your time and exposes understanding gaps and technical barriers while there&amp;rsquo;s still a chance to deal with them.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Get Feedback as you go:&lt;/strong&gt; Similarly, anytime you have a chance to get feedback on work while it is still in process from somebody who might object in the end, do it.  This means instead of building everything at once, work on smaller chunks.  This often takes time and thought, but the earlier you create &lt;em&gt;complete&lt;/em&gt; chunks of code that can be evaluated and ideally shipped on their own, the more likely you are to ship something great in the end.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Optimize your environment:&lt;/strong&gt; Have you spent time figuring out how to work as efficiently as possible?  Have you done it recently?  If not it might be worth re-evaluating your setup on a quarterly basis or so, figuring out what tools you can use to get quicker feedback, and also learning the shortcuts, tricks and new features for the tools that you do use.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ship Code:&lt;/strong&gt; Ultimately the best feedback comes when people are using what you&amp;rsquo;ve written.  Whether that&amp;rsquo;s compliments, bug reports, feature requests, anger or viral adoption, shipping will tell you things that you would never have been certain of while iterating on your own.  If you&amp;rsquo;re struggling to get code out, always fix that first.&lt;/li&gt;
&lt;/ol&gt;
</description>
    </item>
    
    <item>
      <title>Weekly Links: July 28th</title>
      <link>https://benmccormick.org/2018/07/27/weekly-links-july.html</link>
      <pubDate>Fri, 27 Jul 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/07/28/weekly-links-july.html</guid>
      <description>&lt;h3 id=&#34;javascript-and-the-web&#34;&gt;JavaScript and the Web&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://csswizardry.com/2018/07/getting-to-know-a-legacy-codebase/&#34;&gt;Getting to Know a Legacy Codebase Harry Roberts&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I like this advice on approaching a new codebase.  Some of it is CSS specific but the general ideas of tackling the important bits, experimenting with changes, and using tools as much as possible to catch regressions apply across the board.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://medium.com/@Pinterest_Engineering/a-one-year-pwa-retrospective-f4a2f4129e05&#34;&gt;A one year PWA retrospective | Zach Argyle&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;TL;DR: Pinterest saw great results from supplementing their mobile apps with a PWA web app.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://medium.com/ben-and-dion/mission-improve-the-web-ecosystem-for-developers-3a8b55f46411&#34;&gt;Mission: Improve the Web Ecosystem for Developers | Dion Almaer&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I don&amp;rsquo;t know Dion, but this was a wonderful list of challenges that people looking to improve the web platform might want to tackle.  I&amp;rsquo;m excited to see people tackling this stuff.  I&amp;rsquo;m especially interested in what better tools for creating performant sites would look like.&lt;/p&gt;
&lt;h3 id=&#34;technical-deep-dives&#34;&gt;Technical Deep Dives&lt;/h3&gt;
&lt;p&gt;These are long technical articles, and more back end focused then I usually write about on this blog but both touch on things I&amp;rsquo;m interested in and I found them fascinating.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://segment.com/blog/introducing-centrifuge/&#34;&gt;Centrifuge: a reliable system for delivering billions of events per day || Calvin French-Owen&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I had to build an event handling system like this a few years ago, and it&amp;rsquo;s fun to see how the optimal solution changed for Segment as they scaled.  On the backend designs that make no sense for small projects start becoming very real options as a project scales.  That&amp;rsquo;s why it&amp;rsquo;s always worth having some skepticism over the idea that because AppAmaGooFaceSoft are using a technology it must be &amp;ldquo;best in class&amp;rdquo; and we should use it in our small 20 person development team that is facing problems of a completely different scale.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.burntsushi.net/ripgrep/&#34;&gt;ripgrep is faster than {grep, ag, git grep, ucg, pt, sift} | Andrew Gallant&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This piece is structured as a comparison of performance between cli file search tools, but the cool part is the deep insight into text search algorithms and performance tricks littered throughout the benchmark discussions.  It&amp;rsquo;s fascinating to see how heavily optimized for speed these tools are.  Also, I&amp;rsquo;ve been using Ack for 5 years even though I know it&amp;rsquo;s not the fastest tool for searching, because for me it was always &amp;ldquo;fast enough&amp;rdquo; to avoid searching.  But ripgrep appears to be dramatically enough faster in the relatively rare circumstances where I&amp;rsquo;m searching truly large directories of files, that I may finally be up for converting to a new tool.&lt;/p&gt;
&lt;h3 id=&#34;book-review&#34;&gt;Book Review&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://amzn.to/2mPr3zV&#34;&gt;Front-End Reactive Architectures | Luca Mezzalira&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve been very excited to check out this book since I first saw the title pre-release.  I finally had a chance to purchase and read it last month, and I&amp;rsquo;m sad to report that I had fallen prey to the classic mistake of judging a book by it&amp;rsquo;s cover.  I had hoped that this would be a deep dive into architecture and how we structure front end applications, and how reactive programming concepts can impact that.  There&amp;rsquo;s a real dearth of quality high level UI architecture resources out there, so I was genuinely excited about this.&lt;/p&gt;
&lt;p&gt;Unfortunately the book is structured more like a series of loosely related blog posts, first with an overview of older architectural models like MVC, MVP and MVVM, followed by sections looking at several different libraries that use reactive principles: RxJS, Cycle, and MobX.  The latter sections focused more on the nuts and bolts of using the libraries to create simple example apps and less on the impact that using them would have on a large application.  So this is a good book if you want to see some simple code examples of how these libraries work in practice.  But I&amp;rsquo;m still waiting for a great high level front-end architecture book.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Weekly Links: July 20th</title>
      <link>https://benmccormick.org/2018/07/19/weekly-links-july.html</link>
      <pubDate>Thu, 19 Jul 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/07/20/weekly-links-july.html</guid>
      <description>&lt;h3 id=&#34;javascript-and-the-web&#34;&gt;JavaScript and the Web&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://medium.com/google-design/google-photos-45b714dfbed1&#34;&gt;Building the Google Photos Web UI | Antin Harasymiv&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;An amazing detail-laden look at the design and engineering decisions that go into a top of the line web photo experience.  One of the best front end reads I&amp;rsquo;ve seen this year.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://babeljs.io/blog/2018/07/19/whats-happening-with-the-pipeline-proposal&#34;&gt;What’s Happening With the Pipeline (|&amp;gt;) Proposal? | James DiGioia&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;An update on the proposal to add a pipeline operator to JavaScript.  I am not the target audience of this proposal, as I don&amp;rsquo;t regularly write in the nested miniature function style that is aided by this proposal, but I would really love to see some real world code (not fabricated examples) that would have their readability improved by this proposal. The smart pipelines proposal in particular seems like it&amp;rsquo;s adding a bunch of new syntax for developers to learn and tooling to support.  Since this is a &amp;ldquo;sugar&amp;rdquo; feature and doesn&amp;rsquo;t add new capabilities, I really wonder whether it&amp;rsquo;s worth it.&lt;/p&gt;
&lt;h3 id=&#34;leadership-and-teams&#34;&gt;Leadership and Teams&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;http://boz.com/articles/p-rules.html&#34;&gt;The P Rules | Andrew Bosworth&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Design Reviews are one of my favorite parts of my job, and this is a great set of rules for having good ones.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://larahogan.me/blog/feedback-equation/&#34;&gt;Feedback Equation | Lara Hogan&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;So this is back to back weeks with links from Lara, and there&amp;rsquo;s a good reason for it.  This is a great framework for speaking the truth to somebody with humility.&lt;/p&gt;
&lt;h3 id=&#34;startups&#34;&gt;Startups&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://www.atrium.co/blog/b2b-vs-b2c/&#34;&gt;Why I love B2B over B2C | Justin Kan&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve worked at B2B companies my whole career, so I&amp;rsquo;m biased I guess, but unless you just like playing the lottery, its tough to see why you&amp;rsquo;d prefer B2C from a pure financial perspective.&lt;/p&gt;
&lt;h3 id=&#34;random&#34;&gt;Random&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=1-vcErOPofQ&#34;&gt;Grace Hopper on Letterman in 1986 | YouTube&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This clip is just wonderful.  A little slice of history, touching the computer industry, the greatest generation, and the roots of our current late night comedy scene.  &amp;ldquo;There was a time when everyone in this country did one thing together&amp;rdquo; is an amazing statement in our current political environment.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Quick Tip: Logging In Breakpoints</title>
      <link>https://benmccormick.org/2018/07/16/190000.html</link>
      <pubDate>Mon, 16 Jul 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/07/17/190000.html</guid>
      <description>&lt;p&gt;Stop me if this sounds familiar: you see a bug on your site.  You want to know what&amp;rsquo;s going on.  You fire up the developer tools, put a breakpoint in the area you think is a problem, and&amp;hellip; the error doesn&amp;rsquo;t occur while it&amp;rsquo;s being debugged.  Probably it&amp;rsquo;s a timing issue, but I&amp;rsquo;ve also seen situations where pausing on certain breakpoints will actually cause a browser tab to freeze up.  Whatever weirdness you&amp;rsquo;re dealing with, you can&amp;rsquo;t get a breakpoint running in the right spot to see the error.  These are known colloquially as &lt;a href=&#34;https://en.wikipedia.org/wiki/Heisenbug&#34;&gt;Heisenbugs&lt;/a&gt;, bugs that disappear when measured.  Ideally at this point you would add some logging, but if the issue is on production, and you don&amp;rsquo;t know exactly what needs to be logged, that could delay a fix by an unacceptable amount.&lt;/p&gt;
&lt;p&gt;I actually ran into this last night, and decided to test out a tactic I&amp;rsquo;d heard about in a &lt;a href=&#34;https://changelog.com/jsparty/30&#34;&gt;recent JS Party episode&lt;/a&gt;.  Did you know that you can use conditional break points to add temporary logging to a live application?&lt;/p&gt;
&lt;p&gt;Conditional breakpoints are a browser debugger feature where you set a breakpoint, and specify a condition.  The breakpoint only stops the program execution when that condition is truthy.  Here&amp;rsquo;s a video describing the feature in Firefox:&lt;/p&gt;
&lt;iframe width=&#34;560&#34; height=&#34;315&#34; src=&#34;https://www.youtube.com/embed/pVPlMhfrMwM&#34; frameborder=&#34;0&#34; encrypted-media&#34; allowfullscreen&gt;&lt;/iframe&gt;
&lt;p&gt;Conditional breakpoints are useful when you&amp;rsquo;re running through a code path many times during program execution, but you want to stop during a specific run.  But they can also be used to solve our heisenbug problem.  Because the conditional breakpoint executes the code inside of it in the context of the line we&amp;rsquo;re trying to break on, we can actually put logging inside the breakpoint.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;log-example.png&#34;&gt;An example of a console.log inside a breakpoint&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;That &lt;code&gt;console.log&lt;/code&gt; will execute, and because &lt;code&gt;console.log&lt;/code&gt; returns false, the breakpoint will never actually stop.  It&amp;rsquo;s a heisenbug-safe version of watching variables when you&amp;rsquo;re at a breakpoint, and there&amp;rsquo;s no redeploys required.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update January 2019: Chrome will soon be building this hack right into the devtools with a new &amp;ldquo;logpoint&amp;rdquo; option for breakpoints that formalizes this method.  Very cool!&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote class=&#34;twitter-tweet&#34; data-lang=&#34;en&#34;&gt;&lt;p lang=&#34;en&#34; dir=&#34;ltr&#34;&gt;New feature in Chrome 73: Logpoints. Log messages to the Console without cluttering up your code with console.log() calls. &lt;a href=&#34;https://t.co/aFl2e6GmnF&#34;&gt;https://t.co/aFl2e6GmnF&lt;/a&gt; &lt;a href=&#34;https://t.co/fJ6CUNN0Lg&#34;&gt;https://t.co/fJ6CUNN0Lg&lt;/a&gt;&lt;/p&gt;&amp;mdash; Chrome DevTools (@ChromeDevTools) &lt;a href=&#34;https://twitter.com/ChromeDevTools/status/1088463799886200832?ref_src=twsrc%5Etfw&#34;&gt;January 24, 2019&lt;/a&gt;&lt;/blockquote&gt;
</description>
    </item>
    
    <item>
      <title>Prime Generation Revisited</title>
      <link>https://benmccormick.org/2018/07/14/190000.html</link>
      <pubDate>Sat, 14 Jul 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/07/15/190000.html</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve been wanting to try learning a new programming language again for a while, and this weekend decided to play around with &lt;a href=&#34;https://golang.org/&#34;&gt;Go&lt;/a&gt; for the first time in a while.  Go is a statically typed, compiled language useful for systems programming, which makes it a nice complement to my 2 primary languages, JavaScript and Python.  To help myself learn, I decided to revisit the &lt;a href=&#34;https://benmccormick.org/2017/11/28/sieveoferatosthenes/&#34;&gt;Sieve of Eratosthenes problem&lt;/a&gt; that I wrote about last year.  I already had implementations in Python and JavaScript, and thought it would be interesting to see how the code and performance compared.&lt;/p&gt;
&lt;p&gt;As a refresher, the Sieve of Eratosthenes is a method for generating prime numbers by iterating through numbers and marking all multiples of primes we encounter as not prime.  The original algorithm is useful for finding small primes up to a limit, but will eventually consume infinite memory for computers or infinite time for humans.  I used a modified algorithm in my JavaScript implementation that only marks numbers as they become relevant, you can read more details about the problem in &lt;a href=&#34;https://benmccormick.org/2017/11/28/sieveoferatosthenes/&#34;&gt;the original post&lt;/a&gt; but using the JavaScript implementation to generate the 1 millionth prime looks like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;*&lt;/span&gt; generatePrimes() {
    &lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; markedNotPrimeMap &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; Map();
    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; valueToCheck &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt;;
    &lt;span style=&#34;color:#ff79c6&#34;&gt;while&lt;/span&gt;(&lt;span style=&#34;color:#ff79c6&#34;&gt;true&lt;/span&gt;) {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#ff79c6&#34;&gt;!&lt;/span&gt;(markedNotPrimeMap.has(valueToCheck))) {
            &lt;span style=&#34;color:#ff79c6&#34;&gt;yield&lt;/span&gt; valueToCheck
            markedNotPrimeMap.set(valueToCheck&lt;span style=&#34;color:#ff79c6&#34;&gt;**&lt;/span&gt;&lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt;, [valueToCheck])
        } &lt;span style=&#34;color:#ff79c6&#34;&gt;else&lt;/span&gt; {
            &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; primes &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;markedNotPrimeMap.get(valueToCheck)
            primes.forEach(prime=&amp;gt; {
                &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; nextMultipleOfPrime &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; prime &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; valueToCheck;
                &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (markedNotPrimeMap.has(nextMultipleOfPrime)) {
                    markedNotPrimeMap.get(nextMultipleOfPrime).push(prime);
                } &lt;span style=&#34;color:#ff79c6&#34;&gt;else&lt;/span&gt; {
                    markedNotPrimeMap.set(nextMultipleOfPrime, [prime]);
                }
            })
            markedNotPrimeMap.&lt;span style=&#34;color:#ff79c6&#34;&gt;delete&lt;/span&gt;(valueToCheck);
        }
        valueToCheck &lt;span style=&#34;color:#ff79c6&#34;&gt;+=&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;
    }
}
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; counter &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;0&lt;/span&gt;;
&lt;span style=&#34;color:#ff79c6&#34;&gt;for&lt;/span&gt; (&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; p &lt;span style=&#34;color:#ff79c6&#34;&gt;of&lt;/span&gt; generatePrimes()) {
    counter &lt;span style=&#34;color:#ff79c6&#34;&gt;+=&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;;
    &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (counter &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;=&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1000000&lt;/span&gt;) {
        console.log(p);
        &lt;span style=&#34;color:#ff79c6&#34;&gt;break&lt;/span&gt;;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That executes in ~10.5 seconds on my Macbook Pro, and the similar Python implementation averages about 23 seconds.  I was curious how fast a Go solution would execute, since it is known for being fast.&lt;/p&gt;
&lt;p&gt;I put a Go version together like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;package&lt;/span&gt; main

&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;fmt&amp;#34;&lt;/span&gt;
&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;strconv&amp;#34;&lt;/span&gt;

&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;generate_primes&lt;/span&gt;() &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;chan&lt;/span&gt; &lt;span style=&#34;color:#8be9fd&#34;&gt;int&lt;/span&gt; {
    c &lt;span style=&#34;color:#ff79c6&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;make&lt;/span&gt;(&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;chan&lt;/span&gt; &lt;span style=&#34;color:#8be9fd&#34;&gt;int&lt;/span&gt;)
    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; marked_not_prime_map = &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;map&lt;/span&gt;[&lt;span style=&#34;color:#8be9fd&#34;&gt;int&lt;/span&gt;][]&lt;span style=&#34;color:#8be9fd&#34;&gt;int&lt;/span&gt;{}
    &lt;span style=&#34;color:#ff79c6&#34;&gt;go&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;func&lt;/span&gt;() {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;for&lt;/span&gt; value_to_check &lt;span style=&#34;color:#ff79c6&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt;; ; value_to_check&lt;span style=&#34;color:#ff79c6&#34;&gt;++&lt;/span&gt; {
            &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; primes, in_map = marked_not_prime_map[value_to_check]
            &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; !in_map {
                c &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;-&lt;/span&gt; value_to_check
                &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; values []&lt;span style=&#34;color:#8be9fd&#34;&gt;int&lt;/span&gt;
                marked_not_prime_map[value_to_check&lt;span style=&#34;color:#ff79c6&#34;&gt;*&lt;/span&gt;value_to_check] = &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;append&lt;/span&gt;(values, value_to_check)
            } &lt;span style=&#34;color:#ff79c6&#34;&gt;else&lt;/span&gt; {
                &lt;span style=&#34;color:#ff79c6&#34;&gt;for&lt;/span&gt; _, prime &lt;span style=&#34;color:#ff79c6&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;range&lt;/span&gt; primes {
                    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; next_multiple_of_prime &lt;span style=&#34;color:#8be9fd&#34;&gt;int&lt;/span&gt; = prime &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; value_to_check
                    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; next_multiples, next_in_map = marked_not_prime_map[next_multiple_of_prime]
                    &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; next_in_map {
                        marked_not_prime_map[next_multiple_of_prime] = &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;append&lt;/span&gt;(next_multiples, prime)
                    } &lt;span style=&#34;color:#ff79c6&#34;&gt;else&lt;/span&gt; {
                        &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; values []&lt;span style=&#34;color:#8be9fd&#34;&gt;int&lt;/span&gt;
                        marked_not_prime_map[next_multiple_of_prime] = &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;append&lt;/span&gt;(values, prime)
                    }
                }
                &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;delete&lt;/span&gt;(marked_not_prime_map, value_to_check)
            }
        }
    }()

    &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; c
}

&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;main&lt;/span&gt;() {
    c &lt;span style=&#34;color:#ff79c6&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;generate_primes&lt;/span&gt;()
    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; counter &lt;span style=&#34;color:#8be9fd&#34;&gt;int&lt;/span&gt; = &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;
    &lt;span style=&#34;color:#ff79c6&#34;&gt;for&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;true&lt;/span&gt; {
        &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; p &lt;span style=&#34;color:#8be9fd&#34;&gt;int&lt;/span&gt; = &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;-&lt;/span&gt;c
        &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; counter &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;=&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1000000&lt;/span&gt; {
            fmt.&lt;span style=&#34;color:#50fa7b&#34;&gt;Println&lt;/span&gt;(strconv.&lt;span style=&#34;color:#50fa7b&#34;&gt;Itoa&lt;/span&gt;(p))
            &lt;span style=&#34;color:#ff79c6&#34;&gt;break&lt;/span&gt;
        }
        counter&lt;span style=&#34;color:#ff79c6&#34;&gt;++&lt;/span&gt;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The Go version is about 50% longer than the JavaScript version due to boilerplate but is more or less a direct 1 to 1 translation of the JavaScript code.  In Go, generators are created using channels and goroutines.  Goroutines are special functions that can run concurrently to the main thread in Go, and channels are a mechanism for passing data from them, that block the goroutine until the message is received.  So a goroutine that will pass multiple messages through to a channel is essentially equivalent to a Python or JavaScript generator using &lt;code&gt;yield&lt;/code&gt;.  Beyond that, most of the syntax difference is around the ceremony required for using slices in Go , and checking whether an item exists in a map.  Slices are Go&amp;rsquo;s version of a dynamic length array/list, they require an &lt;code&gt;append&lt;/code&gt; function which returns a new slice to add a value.  Go doesn&amp;rsquo;t have a &lt;code&gt;has&lt;/code&gt; method or equivalent on it&amp;rsquo;s map types.  Instead when you attempt to access a value from a map, the map returns 2 values: the received value or the &amp;ldquo;zero value&amp;rdquo; of the map&amp;rsquo;s type and a boolean saying whether the access was successful.  So you have code like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;commits &lt;span style=&#34;color:#ff79c6&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;map&lt;/span&gt;[&lt;span style=&#34;color:#8be9fd&#34;&gt;string&lt;/span&gt;]&lt;span style=&#34;color:#8be9fd&#34;&gt;int&lt;/span&gt;{
    &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;example&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#bd93f9&#34;&gt;100&lt;/span&gt;,
}
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; val, has_val = commits[&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;example&amp;#34;&lt;/span&gt;]  &lt;span style=&#34;color:#6272a4&#34;&gt;// val == 100, has_val == true
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; val2, has_val2 = commits[&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;example2&amp;#34;&lt;/span&gt;]  &lt;span style=&#34;color:#6272a4&#34;&gt;// val == 0, has_val == false
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So does all of this ceremony buy us any performance?  Only a minimal amount in this case.  After timing each script several time the Python code averaged out to 23 seconds, the JavaScript averaged 10.5 seconds, and the Go version averaged 9.5 seconds.  It&amp;rsquo;s the fastest, but only by minimal amounts over the JavaScript.  A good reminder that the algorithm will generally matter more than the programming language for many things, and also that large companies have optimized the heck out of JavaScript in recent years to the point where it&amp;rsquo;s pretty competitive on single threaded performance for many tasks.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Weekly Links: July 13th</title>
      <link>https://benmccormick.org/2018/07/12/weekly-links-july.html</link>
      <pubDate>Thu, 12 Jul 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/07/13/weekly-links-july.html</guid>
      <description>&lt;h3 id=&#34;javascript-and-the-web&#34;&gt;JavaScript and the Web&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://medium.com/p/what-is-jsx-310ab98c463e&#34;&gt;What is JSX? | Kent C Dodds&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;If you were introduced to React &amp;ldquo;all at once&amp;rdquo; and didn&amp;rsquo;t learn it from the basics up, JSX may feel a little bit like magic syntax.  This is a solid explanation of what JSX syntax actually compiles to under the covers.  It demystifies the process and shows that it is all &amp;ldquo;just JavaScript&amp;rdquo; in the end.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://jxnblk.com/writing/posts/defining-component-apis-in-react/&#34;&gt;Defining Component APIs in React | Brent Jackson&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Setting up good interface boundaries between your React components is one of the most important steps you can take to make a React application more maintainable.  This is good solid advice, that I wish I&amp;rsquo;d had when I started building React apps.&lt;/p&gt;
&lt;h3 id=&#34;business-and-leadership&#34;&gt;Business and Leadership&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;http://larahogan.github.io/blog/leadership-style-colors/&#34;&gt;Leadership Style Colors | Lara Hogan&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Lara has put together a thoughtful article about the different ways that leaders need to be able to relate to others.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://m.signalvnoise.com/the-open-plan-office-is-a-terrible-horrible-no-good-very-bad-idea-42bd9cd294e3&#34;&gt;The open-plan office is a terrible, horrible, no good, very bad idea | DHH&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I appear to be in a weird middle ground where I neither love nor hate open offices.  I don&amp;rsquo;t think they&amp;rsquo;re good for my productivity, but I enjoy the people I work with and build more connections with coworkers in an open office than I did when I worked in cubicles. I also find that articles like this tend not to fully grapple with the alternatives.  Most companies aren&amp;rsquo;t mostly remote like Basecamp, and budgeting private offices for all developers is not realistic (especially for the startups called out in this piece due to unknown scaling needs).  So it&amp;rsquo;s remote, open office or cubicle farms, and all three have their detractors.&lt;/p&gt;
&lt;h3 id=&#34;design&#34;&gt;Design&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://uxdesign.cc/designing-for-accessibility-is-not-that-hard-c04cc4779d94&#34;&gt;Designing for accessibility is not that hard | Pablo Stanley&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m embarrassingly ignorant about accessibility concerns, so this was a helpful article for me.  I&amp;rsquo;m going to try and walk through some of these steps on this site to help improve my knowledge here.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://9to5mac.com/2018/07/10/app-store-10-years-design-evolution/&#34;&gt;10 years of the App Store: The design evolution of the earliest apps | 9to5Mac&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This was a really fascinating look at how iPhone app designs have shifted over the years.  9to5Mac took 10 popular apps that were there when the App Store first launched 10 years ago (I&amp;rsquo;ve used 8/10 of these at some point or another) and showed how their UIs and logos had evolved over time.  Interestingly it looks like early 2013, right before the new iOS7 look and feel launched, was the peak point for interface diversity and distinctiveness, as each of these apps had evolved along their own paths.  iOS7 imposed a level of standardization and sameness, and I think apps are just now re-evolving to the point of having truly distinct brand identities on top of that new base.&lt;/p&gt;
&lt;h3 id=&#34;books&#34;&gt;Books&lt;/h3&gt;
&lt;p&gt;I&amp;rsquo;ve been on vacation this week, so here are 2 quicky non-tech book reviews:&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://amzn.to/2L4uGQp&#34;&gt;Golden Days: West&amp;rsquo;s Lakers, Steph&amp;rsquo;s Warriors, and the California Dreamers Who Reinvented Basketball | Jack McCallum&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This was a fun book for basketball lovers.  The sections on Jerry West and the Lakers of the 60s and 70s are more detailed and colorful than the alternating chapters on the modern Warriors, but both are fun, and those interested in how modern Silicon Valley has interacted with the rise of the most popular basketball team in the world will find some interesting tidbits in the modern chapters as well.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://amzn.to/2Jj6vJ2&#34;&gt;American Gods | Neil Gaiman&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A fantasy novel set in modern America.  This one was too crude for me to recommend unreservedly, but it contains a huge number of cool images and ideas, and I don&amp;rsquo;t regret reading it.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Book Review: The Five Dysfunctions of a Team</title>
      <link>https://benmccormick.org/2018/07/08/190000.html</link>
      <pubDate>Sun, 08 Jul 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/07/09/190000.html</guid>
      <description>&lt;p&gt;The nice thing about team books is that they&amp;rsquo;re talking about a subject that almost everybody can relate to.  &lt;a href=&#34;https://amzn.to/2u2aPrm&#34;&gt;The Five Dysfunctions of a Team&lt;/a&gt; by Patrick Lencioni is a book for leaders, but it&amp;rsquo;s also a book for anyone who wants to better understand why they problems they see in their teams occur, and what needs to change to make them better.&lt;/p&gt;
&lt;p&gt;The Five Dysfunctions is a leadership fable, a story told to illustrate the principals of a business model.  I&amp;rsquo;ve found that I enjoy this teaching style, I also loved &lt;a href=&#34;https://amzn.to/2KHf3Ps&#34;&gt;Death By Meeting&lt;/a&gt; and &lt;a href=&#34;https://amzn.to/2KXOkxh&#34;&gt;The Goal&lt;/a&gt;, which employee the same style.  The beauty of fables is the way they allow you to soak into a scenario, and connect it to your own experiences and relationships.  Then as the principles the author wants to teach unfold, they take advantage of those connections to spark ideas for application.  At least that&amp;rsquo;s the theory.&lt;/p&gt;
&lt;p&gt;The Five Dysfunctions is of course, about how teams go wrong.  I won&amp;rsquo;t spoil the contents too much, but ultimately, team failures aren&amp;rsquo;t about technique or distinct decisions, but human beings and how we relate to each other.  This book both clearly defines a set of those problems, and then gives concrete suggestions for improving a team when they&amp;rsquo;re present.  It&amp;rsquo;s a classic, and I found it as thought provoking as I expected.  I definitely recommend it for anyone who wants to better understand how teams work, and how they fail.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Weekly Links: July 8th</title>
      <link>https://benmccormick.org/2018/07/07/weekly-links-july.html</link>
      <pubDate>Sat, 07 Jul 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/07/08/weekly-links-july.html</guid>
      <description>&lt;p&gt;A small list this week as it&amp;rsquo;s a holiday in the states.  So fewer articles out there, and I&amp;rsquo;m sure I missed some of them.&lt;/p&gt;
&lt;h3 id=&#34;programmer-life&#34;&gt;Programmer Life&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;http://firstround.com/review/my-lessons-from-interviewing-400-engineers-over-three-startups/&#34;&gt;My Lessons from Interviewing 400+ Engineers | First Round Review&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m nowhere near Marco&amp;rsquo;s experience level interviewing, but his advice in this &amp;ldquo;interview on interviewing&amp;rdquo; resonates with my experience.  Things that stood out to me:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Don&amp;rsquo;t overoptimize on a specific skillset as a startup, since you don&amp;rsquo;t know what skills you need yet.&lt;/li&gt;
&lt;li&gt;It&amp;rsquo;s incredibly important (but also quite difficult) to be consistent in your standards across all interviewees&lt;/li&gt;
&lt;li&gt;Team interviewing works better than 1 on 1 interviews for evaluating technical skills and team fit.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&#34;https://lethain.com/digg-v4/&#34;&gt;Digg’s v4 launch: an optimism born of necessity | Will Larson&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;An engineering horror story.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://randsinrepose.com/archives/anti-flow/&#34;&gt;Anti-Flow | Rands in Repose&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Rands remains my favorite software blog because of his ability to capture truths about the engineer condition with beautiful words.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Evil JavaScript</title>
      <link>https://benmccormick.org/2018/07/03/190000.html</link>
      <pubDate>Tue, 03 Jul 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/07/04/190000.html</guid>
      <description>&lt;p&gt;JavaScript developers sometimes complain that their language is unjustly maligned for having too many confusing features.  Plenty of other people are out there explaining why this is misguided, but for this post I want to lean in.  Rather than falling into the &lt;em&gt;traps&lt;/em&gt; that JavaScript exposes you to, what if we embrace our language&amp;rsquo;s reputation instead, and see what code we can write if we don&amp;rsquo;t care about the feelings of others?&lt;/p&gt;
&lt;p&gt;The &amp;ldquo;Evil JavaScript&amp;rdquo; you&amp;rsquo;ll see today takes advantage of an array of language features. Many of these techniques still work in other languages, so please don&amp;rsquo;t worry that I&amp;rsquo;m limiting your pursuit of the dark side. But JavaScript certainly has a flair for evil that is hard to match.  If you write code that other people have to work with, the opportunities to annoy, confuse, aggravate and bamboozle are limitless.  The following is a small selection of choice techniques.&lt;/p&gt;
&lt;h4 id=&#34;modify-objects-in-your-getters&#34;&gt;Modify objects in your getters&lt;/h4&gt;
&lt;p&gt;JavaScript objects can define &lt;code&gt;getters&lt;/code&gt;, functions that let you access the result of a function as a property.  Used normally, that looks like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; greeter &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {
  name&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Bob&amp;#39;&lt;/span&gt;,
  get hello() { &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;`Hello &lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.name&lt;span style=&#34;color:#f1fa8c&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;`&lt;/span&gt;}
}
console.log(greeter.hello) &lt;span style=&#34;color:#6272a4&#34;&gt;// Hello Bob
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;greeter.name &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;World&amp;#39;&lt;/span&gt;;
console.log(greeter.hello) &lt;span style=&#34;color:#6272a4&#34;&gt;// Hello World
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Used evilly though, we can come up with fun self-destructing objects!&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; obj &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {
   foo&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;,
   bar&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt;,
   baz&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;3&lt;/span&gt;,
   get evil() {
      &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; keys &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;Object&lt;/span&gt;.keys(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;);
      &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt;(keys) {
         &lt;span style=&#34;color:#ff79c6&#34;&gt;delete&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;[keys[&lt;span style=&#34;color:#bd93f9&#34;&gt;0&lt;/span&gt;]]
      }
      &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Nothing to see here&amp;#39;&lt;/span&gt;;
   }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Here, every time we read &lt;code&gt;obj.evil&lt;/code&gt;, we delete one of the other properties on the object, with no indication to the code accessing &lt;code&gt;obj.evil&lt;/code&gt; that anything extraordinary is happening.  But this is just the start of how we can introduce unexpected side effects.&lt;/p&gt;
&lt;h4 id=&#34;nobody-expects-a-proxy&#34;&gt;Nobody expects a Proxy!&lt;/h4&gt;
&lt;p&gt;Getters are cool and all, but they&amp;rsquo;ve been around for years, and many developers know about them.  We now have an even more powerful variation on the same theme with Proxies.  Proxies are an ES6 feature that let you put a wrapper class around an object that lets you control what happens when a user accesses or updates any property.  So we can, for instance define an object that will, one third of the time return a value from a random key whenever a user tries to access a key.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; obj &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {a&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;, b&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt;, c&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;3&lt;/span&gt;};

&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; handler &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {
    get&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(obj, prop) {
      &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;Math&lt;/span&gt;.random() &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;0.33&lt;/span&gt;) {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; obj[prop];
      } &lt;span style=&#34;color:#ff79c6&#34;&gt;else&lt;/span&gt; {
        &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; keys &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;Object&lt;/span&gt;.keys(obj);
        &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; key &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; keys[&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;Math&lt;/span&gt;.floor(&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;Math&lt;/span&gt;.random()&lt;span style=&#34;color:#ff79c6&#34;&gt;*&lt;/span&gt;keys.length)]
        &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; obj[key];
      }
    }
};

&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; evilObj &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;Proxy&lt;/span&gt;(obj, handler);

&lt;span style=&#34;color:#6272a4&#34;&gt;// this is example output that I received running the code
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;console.log(evilObj.a); &lt;span style=&#34;color:#6272a4&#34;&gt;// 1
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;console.log(evilObj.b); &lt;span style=&#34;color:#6272a4&#34;&gt;// 1
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;console.log(evilObj.c); &lt;span style=&#34;color:#6272a4&#34;&gt;// 3
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;console.log(evilObj.a); &lt;span style=&#34;color:#6272a4&#34;&gt;// 2
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;console.log(evilObj.b); &lt;span style=&#34;color:#6272a4&#34;&gt;// 2
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;console.log(evilObj.c); &lt;span style=&#34;color:#6272a4&#34;&gt;// 3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Our sneakiness is undermined a bit by devtools, where evilObj will be identified as a Proxy, but we can still lead other developers on a merry chase before we&amp;rsquo;re caught.&lt;/p&gt;
&lt;h4 id=&#34;contagious-functions&#34;&gt;Contagious functions&lt;/h4&gt;
&lt;p&gt;So far we&amp;rsquo;ve talked about how objects can modify themselves, but we can also create innocuous looking functions that infect the objects that are passed to them with strange behavior.  For instance lets say we had a simple &lt;code&gt;get&lt;/code&gt; function to do safe property lookups on an object that may not exist:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; get &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; (obj, property, &lt;span style=&#34;color:#ff79c6&#34;&gt;default&lt;/span&gt;) =&amp;gt; {
   &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt;(&lt;span style=&#34;color:#ff79c6&#34;&gt;!&lt;/span&gt;obj) {
      &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;default&lt;/span&gt;;
   }
   &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; obj[property];
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It would be easy to make that function contagious by subtly changing the object it was passed.  For instance we could make it so the retrieved property no longer showed up when the user enumerates the keys.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; get &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; (obj, property, defaultValue) =&amp;gt; {
   &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt;(&lt;span style=&#34;color:#ff79c6&#34;&gt;!&lt;/span&gt;obj &lt;span style=&#34;color:#ff79c6&#34;&gt;||&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;!&lt;/span&gt;property &lt;span style=&#34;color:#ff79c6&#34;&gt;in&lt;/span&gt; obj) {
      &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; defaultValue;
   }
   &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; value &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; obj[property];
   &lt;span style=&#34;color:#ff79c6&#34;&gt;delete&lt;/span&gt; obj[property];
   &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;Object&lt;/span&gt;.defineProperty(obj, property, {
      value,
      enumerable&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;false&lt;/span&gt;
   })
   &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; obj[property];
}

&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; x &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {a&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;, b&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt; };

console.log(&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;Object&lt;/span&gt;.keys(x)); &lt;span style=&#34;color:#6272a4&#34;&gt;// [&amp;#39;a&amp;#39;, &amp;#39;b&amp;#39;]
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;console.log(get(x, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;));
console.log(&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;Object&lt;/span&gt;.keys(x)); &lt;span style=&#34;color:#6272a4&#34;&gt;// [&amp;#39;b&amp;#39;]
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is super subtle, since enumeration is neither rare nor particularly common.  Since the actual bug wouldn&amp;rsquo;t be tied to the infected object at all, it could persist in a code base for a long time.&lt;/p&gt;
&lt;h4 id=&#34;messing-with-prototypes&#34;&gt;Messing with Prototypes&lt;/h4&gt;
&lt;p&gt;Sometimes the old ways are best.  One of the most criticized features of the JavaScript language is the ability to modify built-in prototypes.  This was used in the early days of JavaScript to enhance built in objects like arrays.  For instance we can add a &lt;code&gt;contains&lt;/code&gt; function for arrays like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;Array&lt;/span&gt;.prototype.contains &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(item) {
  &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.indexOf(item) &lt;span style=&#34;color:#ff79c6&#34;&gt;!==&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It turns out that doing this in real libraries can &lt;a href=&#34;http://2ality.com/2016/02/array-prototype-includes.html#frequently-asked-questions&#34;&gt;ruin the language for everyone else&lt;/a&gt;.  So providing additional useful prototype methods is a good long con for malicious developers with patience.  But for the impatient sociopaths reading along, we also have some short term fun we can unleash.  The fun thing about prototype manipulation is that it affects all code running in an environment, even if that code is running in modules or closures.  So if we introduce the following code as a 3rd party script (maybe an ad or analytics script?), we can introduce subtle bugs throughout a site.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;Array&lt;/span&gt;.prototype.map &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(fn) {
   &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; arr &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;;
   &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; arr2 &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; arr.reduce((acc, val, idx) =&amp;gt; {
      &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;Math&lt;/span&gt;.random() &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;0.95&lt;/span&gt;) {
         idx &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; idx &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;
      }
      &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; index &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; acc.length &lt;span style=&#34;color:#ff79c6&#34;&gt;-&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;===&lt;/span&gt; idx &lt;span style=&#34;color:#ff79c6&#34;&gt;?&lt;/span&gt; (idx &lt;span style=&#34;color:#ff79c6&#34;&gt;-&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt; ) &lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; idx
      acc[index] &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; fn(val, index, arr);
      &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; acc;
   },[]);
   &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; arr2;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We&amp;rsquo;ve rewritten &lt;code&gt;Array.prototype.map&lt;/code&gt; to work just like normal &lt;code&gt;map&lt;/code&gt; with the exception that we will randomly switch the order of 2 values 1/20th of the time.  An example result:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; arr &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; [&lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;,&lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt;,&lt;span style=&#34;color:#bd93f9&#34;&gt;3&lt;/span&gt;,&lt;span style=&#34;color:#bd93f9&#34;&gt;4&lt;/span&gt;,&lt;span style=&#34;color:#bd93f9&#34;&gt;5&lt;/span&gt;,&lt;span style=&#34;color:#bd93f9&#34;&gt;6&lt;/span&gt;,&lt;span style=&#34;color:#bd93f9&#34;&gt;7&lt;/span&gt;,&lt;span style=&#34;color:#bd93f9&#34;&gt;8&lt;/span&gt;,&lt;span style=&#34;color:#bd93f9&#34;&gt;9&lt;/span&gt;,&lt;span style=&#34;color:#bd93f9&#34;&gt;10&lt;/span&gt;,&lt;span style=&#34;color:#bd93f9&#34;&gt;11&lt;/span&gt;,&lt;span style=&#34;color:#bd93f9&#34;&gt;12&lt;/span&gt;,&lt;span style=&#34;color:#bd93f9&#34;&gt;13&lt;/span&gt;,&lt;span style=&#34;color:#bd93f9&#34;&gt;14&lt;/span&gt;,&lt;span style=&#34;color:#bd93f9&#34;&gt;15&lt;/span&gt;];
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; square &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; x =&amp;gt; x &lt;span style=&#34;color:#ff79c6&#34;&gt;*&lt;/span&gt; x;
console.log(arr.map(square));
&lt;span style=&#34;color:#6272a4&#34;&gt;// [1,4,9,16,25,36,49,64,100,81,121,144,169,196,225
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;console.log(arr.map(square));
&lt;span style=&#34;color:#6272a4&#34;&gt;// [1,4,9,16,25,36,49,64,81,100,121,144,169,196,225]
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;console.log(arr.map(square));
&lt;span style=&#34;color:#6272a4&#34;&gt;// [1,4,9,16,25,36,49,64,81,100,121,144,169,196,225]
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We ran map 3 times, and the first was subtly different than the next 2 runs.  It&amp;rsquo;s subtle enough that it won&amp;rsquo;t always cause anything to happen, and the crazy thing about this hack is that there&amp;rsquo;s no real way to know it&amp;rsquo;s happening without actually reading the source code that caused it.  Our function doesn&amp;rsquo;t show up weirdly in devtools, and it doesn&amp;rsquo;t error under strict mode or anything else.  This is how developers go mad.&lt;/p&gt;
&lt;h4 id=&#34;naming-things-is-hard&#34;&gt;Naming things is hard&lt;/h4&gt;
&lt;p&gt;As one of the 2 hard problems in Computer Science, you don&amp;rsquo;t have to be evil to come up with bad names&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.  But it certainly doesn&amp;rsquo;t hurt.  We&amp;rsquo;ll pass over the chump change of misleading names and outdated comments.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;// initialize a date
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; arrayOfNumbers &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; { userid&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;, name&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Darth Vader&amp;#39;&lt;/span&gt;};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;No let&amp;rsquo;s get to the good stuff.  Did you know that much of unicode can be used to name variables in JavaScript?  If you&amp;rsquo;re into fun and games of course, this means that emoji are in play:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; 💩 &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; { postid&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;123&lt;/span&gt;, postName&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Evil JavaScript&amp;#39;&lt;/span&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;But we want evil JavaScript, so let&amp;rsquo;s go straight to lookalike characters.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; oｂj &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {};
console.log(obj); &lt;span style=&#34;color:#6272a4&#34;&gt;// Error!
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The &lt;code&gt;ｂ&lt;/code&gt; in &lt;code&gt;oｂj&lt;/code&gt; may look normal, but it is actually a &lt;em&gt;fullwidth latin small letter b&lt;/em&gt; instead of a &lt;em&gt;latin small letter b&lt;/em&gt;, and that distinction means that anyone typing in the variable directly is probably going to be very confused.&lt;/p&gt;
&lt;h3 id=&#34;dont-be-evil&#34;&gt;Don&amp;rsquo;t be evil&lt;/h3&gt;
&lt;p&gt;Despite appearances, it is the official position of this blog that evil JavaScript should not be encouraged and may in fact be harmful.  That said, it&amp;rsquo;s always good to know the ways things can go wrong. Each of these patterns exist out in the wild somewhere.  Hopefully in less malicious forms than I&amp;rsquo;ve shown here.  But lack of intent doesn&amp;rsquo;t make them easier to debug, and knowing just how bad things can get is a good start to seeing these bugs coming.  You never know what bug is sitting out there waiting to strike. Just because you&amp;rsquo;re paranoid doesn&amp;rsquo;t mean that they&amp;rsquo;re not out to get you.&lt;/p&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;This may be hard to believe for old time Linux folks of course. They&amp;rsquo;ve had years to associate the worst naming offender in the industry (Microsoft) with the deepest forms of evil.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>Book Review: Atomic Design</title>
      <link>https://benmccormick.org/2018/07/01/190000.html</link>
      <pubDate>Sun, 01 Jul 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/07/02/190000.html</guid>
      <description>&lt;p&gt;The Unix philosophy for designing software, &amp;ldquo;Make each program do one thing well&amp;rdquo;, is a piece of wisdom that goes beyond just programming.  For instance, it also applies to non-fiction writing.  When learning, I find that I gravitate towards small focused resources, rather than monolithic books or websites that aim to teach everything about a specific topic.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://atomicdesign.bradfrost.com/&#34;&gt;Atomic Design&lt;/a&gt; by Brad Frost is a book that does one thing really well: it explains what a design system is, and how you can implement one in your organization.  It doesn&amp;rsquo;t try to be a book about CSS, design styles or any of the other myriad topics that touch against design systems.  That focus serves it well, and I found it to be well worth my time.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://bradfrost.com/blog/link/design-systems/&#34;&gt;Design Systems&lt;/a&gt;  are an organized toolkit for creating digital products.  They&amp;rsquo;re a set of elements, widgets, patterns, and layouts (atoms, molecules, organisms and templates in the language of the book) that can be combined to build complex sites and applications.  The idea is pretty simple.  But there are some real challenges in implementing one.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;em&gt;What content belongs in a design system?  Where do we draw the boundary as to what belongs and what doesn&amp;rsquo;t?&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;How do you build a tool for your design system so that patterns are easily findable, usable, and understandable?&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;How do you keep a design system relevant over time as the product(s) change?&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;How do you convince budget-conscious organizations that maintaining a design system is a good use of time and money?&lt;/em&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;After a brief introduction to the ideas behind design systems and pattern libraries, these are the challenges that Atomic design tackles.  It discusses a hierarchy for patterns, and methods for pulling them out of existing applications, then moves on to talking about tools for implementing a pattern library, and techniques for navigating organizational politics when starting and maintaining a design system.&lt;/p&gt;
&lt;p&gt;So this book &lt;strong&gt;will be helpful&lt;/strong&gt; for you if you are&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Struggling to deal with inconsistencies in your interfaces, or constantly doing custom UI work for each new feature&lt;/li&gt;
&lt;li&gt;Considering implementing a design system/pattern library for your organization&lt;/li&gt;
&lt;li&gt;Hoping to learn more about design systems because somebody else in your organization is pushing for one&lt;/li&gt;
&lt;li&gt;Having trouble maintaining an existing pattern library&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;It &lt;strong&gt;won&amp;rsquo;t be helpful&lt;/strong&gt; for you if you are&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Looking for tips on how to make your interface beautiful&lt;/li&gt;
&lt;li&gt;Seeking hands on information about specific design, CSS or JavaScript techniques&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I enjoyed Atomic Design a lot, and hope that I&amp;rsquo;ll get to use what I&amp;rsquo;ve learned in the near future.  As far as I can tell, Atomic design is only available on &lt;a href=&#34;http://atomicdesign.bradfrost.com/&#34;&gt;Brad Frost&amp;rsquo;s site&lt;/a&gt;.  You can read the book online there, or buy the paperback version.  If you fall into one of the 4 categories I listed above, I&amp;rsquo;d highly recommend checking it out.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Weekly Links: June 30th</title>
      <link>https://benmccormick.org/2018/06/29/weekly-links-june.html</link>
      <pubDate>Fri, 29 Jun 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/06/30/weekly-links-june.html</guid>
      <description>&lt;h3 id=&#34;javascript--the-web&#34;&gt;JavaScript &amp;amp; The Web&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://www.merrickchristensen.com/articles/headless-user-interface-components/&#34;&gt;Headless User Interface | Merrick Christensen&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;UI mixins are one of the hardest problems to solve.  Sharing &amp;ldquo;behavior&amp;rdquo; across multiple UI components is difficult to do right.  Merrick has documented an emerging pattern for doing this with React.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://medium.com/airbnb-engineering/react-native-at-airbnb-f95aa460be1c&#34;&gt;React Native at Airbnb | Airbnb Engineering&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This has gotten plenty of attention around the internet, but Airbnb is moving away from React Native after years of heavy use and contributions to the community.  Worth reading as an explanation of the pluses and minuses of React Native, probably not worth reading too much into the move beyond that.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://remysharp.com/2018/06/26/an-adventure-in-sparse-arrays&#34;&gt;An Adventure in Sparse Arrays | Remy Sharp&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;For anyone who read my &lt;a href=&#34;https://benmccormick.org/2018/06/19/code-golf-sparse-arrays/&#34;&gt;&amp;ldquo;sparse array code golf&amp;rdquo; post&lt;/a&gt; the other day, this is a better holistic look at sparse arrays in JavaScript.  I learned several new things here.&lt;/p&gt;
&lt;h3 id=&#34;programming-practices&#34;&gt;Programming Practices&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://medium.com/@ricomariani/understanding-performance-regions-e4b6e09a94da&#34;&gt;Understanding Performance Regions | Rico Mariani&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This is a nice high level post about a different way to think about performance monitoring and improvement.&lt;/p&gt;
&lt;h3 id=&#34;fun&#34;&gt;Fun&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=QjvzCTqkBDQ&amp;amp;feature=youtu.be&#34;&gt;Paul McCartney Carpool Karaoke&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;An incredibly fun video.  Paul McCartney showing James Corden around Liverpool.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.bloomberg.com/news/features/2018-06-21/how-nintendo-s-switch-helped-the-japanese-gaming-giant-win-again&#34;&gt;The Legend of Nintendo | Bloomberg&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A great writeup on Nintendo&amp;rsquo;s last few years and where they stand now.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>JavaScript “Stale Practices”</title>
      <link>https://benmccormick.org/2018/06/25/190000.html</link>
      <pubDate>Mon, 25 Jun 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/06/26/190000.html</guid>
      <description>&lt;p&gt;Best practices don&amp;rsquo;t last forever. This is especially true when a field is changing fast, and JavaScript development has changed a lot over the past 10 years.  The old best practices go stale, and new ones take their place.  Here are 5 JavaScript best practices that have gone stale recently.&lt;/p&gt;
&lt;h4 id=&#34;using-the-strict-mode-pragma-to-opt-in-to-a-sane-javascript-subset&#34;&gt;Using the strict mode pragma to opt in to a sane JavaScript subset&lt;/h4&gt;
&lt;p&gt;When &lt;a href=&#34;https://benmccormick.org/2015/09/14/es5-es6-es2016-es-next-whats-going-on-with-javascript-versioning&#34;&gt;ECMAScript 5&lt;/a&gt; was released, it introduced a special &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode&#34;&gt;strict mode&lt;/a&gt; that tweaks the behavior of some obscure features of the language.  Now, when a function or script file starts with the string &lt;code&gt;&#39;use strict&#39;&lt;/code&gt;, code in that scope works differently than the same code without the &lt;code&gt;&#39;use strict&#39;&lt;/code&gt; string.  Expressions that look like a mistake are flagged as an error instead of being ignored, code is restricted in ways that make it easier to optimize performance, and terms that may be used in future JavaScript versions are reserved as keywords and you can&amp;rsquo;t use them as names for variables.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;use strict&amp;#39;&lt;/span&gt;;
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; objWithDuplicates &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {x&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;, x&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt;}; &lt;span style=&#34;color:#6272a4&#34;&gt;// Fine normally, an error in strict mode
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;with&lt;/span&gt;(objWithDuplicates) { &lt;span style=&#34;color:#6272a4&#34;&gt;// with expressions are syntax errors in strict mode
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    console.log(x);
}
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;private&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;top secret&amp;#39;&lt;/span&gt;; &lt;span style=&#34;color:#6272a4&#34;&gt;// this is a ReferenceError in strict mode
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Strict mode was a nice small improvement in JavaScript, and a good way to move past some of the mistakes of the past like &lt;code&gt;with&lt;/code&gt; expressions.  But even though it was a good idea to use, and I was adding the silly &lt;code&gt;&#39;use strict&#39;&lt;/code&gt; string to the start of all my functions for a few years, this is no longer necessary for many people.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;use strict&lt;/code&gt; string was necessary because the language designers wanted to maintain backwards compatibility, and they needed a way for developers to signal that they were writing new code that they were comfortable holding to a higher standard.  ECMAScript 2015 (&lt;a href=&#34;https://benmccormick.org/2015/09/14/es5-es6-es2016-es-next-whats-going-on-with-javascript-versioning&#34;&gt;ES6&lt;/a&gt;) provided a better way of doing that.  &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export&#34;&gt;JavaScript Modules&lt;/a&gt; are a new type of script, and browsers can be confident that scripts loaded that way have been edited in a ES2015+ world.  Because of that confidence, JavaScript modules are strict mode by default.  So if you are using &lt;code&gt;import&lt;/code&gt; and &lt;code&gt;export&lt;/code&gt; in your code, you can stop adding &lt;code&gt;&#39;use strict&#39;&lt;/code&gt; everywhere and just rely on the browser to do the right thing.  If you&amp;rsquo;re compiling through &lt;a href=&#34;https://babeljs.io/&#34;&gt;Babel&lt;/a&gt; or other tools you&amp;rsquo;ll still be ok, as they add the strict mode pragma for you when they compile your classes down to ES5 code.&lt;/p&gt;
&lt;h4 id=&#34;using-anonymous-functions-when-dealing-with-async-code-in-loops&#34;&gt;Using anonymous functions when dealing with async code in loops&lt;/h4&gt;
&lt;p&gt;For many years, JavaScript&amp;rsquo;s many async use cases combined with the way &lt;code&gt;var&lt;/code&gt; works to create a classic programmer trap.  Here&amp;rsquo;s some jQuery code to put a listener on a series of buttons and alert a different number for each one of them.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;for&lt;/span&gt; (&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; i &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;0&lt;/span&gt;; i &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt; buttons.length; i &lt;span style=&#34;color:#ff79c6&#34;&gt;++&lt;/span&gt; ) {
    $(buttons[i]).click(&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;() {
        alert(i &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;);
    });
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The idea is that if we have a list of 10 buttons, after we run this code clicking the first one will alert &lt;code&gt;1&lt;/code&gt;, the next one &lt;code&gt;2&lt;/code&gt;, and so on.  The problem is&amp;hellip; it doesn&amp;rsquo;t work.  If there is a list of 10 buttons, all of them will alert &lt;code&gt;10&lt;/code&gt; when clicked.  But why?   The problem is that &lt;code&gt;var&lt;/code&gt; doesn&amp;rsquo;t create a new variable for each run of the loop.  The technical term here is that &lt;code&gt;var&lt;/code&gt; isn&amp;rsquo;t &lt;em&gt;block-scoped&lt;/em&gt;.  It isn&amp;rsquo;t limited by a set of curly braces, when &lt;code&gt;var&lt;/code&gt; is called, it creates a variable that is accessible anywhere inside the function that contains it, or it creates a property on the global object if there is no containing function.  So when we run our loop, we aren&amp;rsquo;t creating 10 separate &lt;code&gt;i&lt;/code&gt; values, we&amp;rsquo;re creating 1 &lt;code&gt;i&lt;/code&gt; value and updating it 9 times.  Since the click handlers don&amp;rsquo;t run until the user has clicked the button, &lt;code&gt;i&lt;/code&gt; has been updated all the way to 9, and every button references it and alerts &lt;code&gt;10&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;For years, the recommended way of working around issues like this was to create an inner function.  Because JavaScript variables are function scoped, we can create a new function, pass it the current i value, and execute the function immediately.  When the click handler executes, it will have a reference to the arguments from the inner function, and will receive the correct variable value.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;for&lt;/span&gt; (&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; i &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;0&lt;/span&gt;; i &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt; buttons.length; i &lt;span style=&#34;color:#ff79c6&#34;&gt;++&lt;/span&gt; ) {
    (&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(innerI) {
        $(buttons[innerI]).click(&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;() {
            alert(innerI &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;);
        });
    })(i);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This example works, but it&amp;rsquo;s obviously a bit convoluted, and would not look straightforward to a new JavaScript programmer who came across it.  It gives off some unmistakable &amp;ldquo;magic function&amp;rdquo; vibe.  Fortunately we can do better nowadays.&lt;/p&gt;
&lt;p&gt;ECMAScript 2015 introduced the block scoped variable types &lt;code&gt;let&lt;/code&gt; and &lt;code&gt;const&lt;/code&gt;.  Now we can create loop iterators that stay scoped to the loop portion that they were assigned in.  This allows us to re-simplify our code, but have it actually work.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;for&lt;/span&gt; (&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; i &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;0&lt;/span&gt;; i &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt; buttons.length; i &lt;span style=&#34;color:#ff79c6&#34;&gt;++&lt;/span&gt; ) {
    $(buttons[i]).click(() =&amp;gt; alert(i &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;));
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;using-closures-for-all-of-our-private-variables&#34;&gt;Using closures for all of our private variables&lt;/h4&gt;
&lt;p&gt;JavaScript has never had a first class method for creating objects with private state.  Any normal object you create will have all its properties available for reading and editing by any code that has access to it.  But there has always been a workaround.  We can once again take advantage of JavaScript&amp;rsquo;s function scope.  This time we can write a function that creates an object.  The methods of that object will have access to any other variables inside that function.  This is called a closure.  A closure is a function that returns another function that maintains access to the outer function state.  In this case the returned function will be a method on an object.  Here&amp;rsquo;s an example with a user, where the id is only readable and the name can only be updated with explicit get and set commands, which won&amp;rsquo;t accept a falsy value:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt; createUser(name) {
    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; id &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; uuid();
    &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; {
        getID() { &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; id },
        getName() { &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; name },
        setName(_name) { name &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; _name &lt;span style=&#34;color:#ff79c6&#34;&gt;||&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Unknown&amp;#39;&lt;/span&gt;},
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This object factory pattern is still useful today, but sometimes we want something a bit more object oriented.  Fortunately there are now more ways of doing these things. ES2015 introduced the &lt;code&gt;Symbol&lt;/code&gt; keyword.  Symbols are unique values that can only be accessed by code that has a reference to the symbol.  So we can use a symbol as a more advanced version of our factory code above, creating a class that accesses it&amp;rsquo;s private state via a symbol.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; ID &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; Symbol();
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; NAME &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; Symbol();

&lt;span style=&#34;color:#ff79c6&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; User {
    constructor(name) {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;[ID] &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; uuid();
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;[NAME] &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; name;
    }
    get id() { &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;[ID]}
    get name() { &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;[NAME]}
    set name(name) { &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;[NAME] &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; name &lt;span style=&#34;color:#ff79c6&#34;&gt;||&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Unkown&amp;#39;&lt;/span&gt;}
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This allows us to keep all of our private state local to the object rather than in a separate closure, and our objects with private state can be created with class constructor syntax when that is preferred or required.&lt;/p&gt;
&lt;p&gt;I want to note that this new best practice will likely become stale itself soon.  TC39 is considering a proposal to add explicit private state to classes.  It is currently in &lt;a href=&#34;https://ponyfoo.com/articles/tc39-ecmascript-proposals-future-of-javascript#stage-3&#34;&gt;stage 3&lt;/a&gt; with TC39 and is likely to become a part of the language.  In the proposal, private state would look like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; User {
    #id &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; uuid()
    #name &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Unknown&amp;#39;&lt;/span&gt;

    constructor(name) {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;#name &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; name;
    }
    get id() { &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.#id}
    get name() { &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.#name}
    set name(name) { &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.#name &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; name &lt;span style=&#34;color:#ff79c6&#34;&gt;||&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Unkown&amp;#39;&lt;/span&gt;}
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;reading-arguments-to-create-variadic-functions&#34;&gt;Reading &lt;code&gt;arguments&lt;/code&gt; to create variadic functions&lt;/h4&gt;
&lt;p&gt;Variadic functions are functions that may contain  different numbers of arguments when called.  For instance, a sum function that takes multiple arguments and adds them all together.  Prior to ES6, this was accomplished by using the special &lt;code&gt;arguments&lt;/code&gt; variable.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt; sum() {
    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; len &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; arguments.length;
    &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (len &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt;) {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;throw&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Sum requires at least 2 arguments&amp;#39;&lt;/span&gt;
    }
    &lt;span style=&#34;color:#6272a4&#34;&gt;// convert arguments to a &amp;#34;real array&amp;#34;
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; args &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;Array&lt;/span&gt;.prototype.slice.call(arguments);
    &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; args.reduce(&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(a, b) { &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; a &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; b}, &lt;span style=&#34;color:#bd93f9&#34;&gt;0&lt;/span&gt;);
}
&lt;span style=&#34;color:#6272a4&#34;&gt;// sum(1,2) === 3
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;// sum(1, 10, 20) === 31
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Using arguments is a bit messy.  First, it&amp;rsquo;s a magic variable like &lt;code&gt;this&lt;/code&gt; that is automatically available in the scope of any function.  This isn&amp;rsquo;t obvious to people who don&amp;rsquo;t know about it.  Second, it&amp;rsquo;s not a &amp;ldquo;real array&amp;rdquo;, it&amp;rsquo;s an &amp;ldquo;array-like object&amp;rdquo;, and thus it doesn&amp;rsquo;t have useful methods like &lt;code&gt;map&lt;/code&gt;, &lt;code&gt;filter&lt;/code&gt;, &lt;code&gt;reduce&lt;/code&gt; available on its prototype.  You always have to deal with the whole object, even if you have some named arguments and some unnamed ones.   But ES6 provided a better solution with rest parameters.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt; sum(...nums) {
    &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (nums.length &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt;)
        &lt;span style=&#34;color:#ff79c6&#34;&gt;throw&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Sum requires at least 2 arguments&amp;#39;&lt;/span&gt;
    }
    &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; nums.reduce((a, b) =&amp;gt; a &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; b, &lt;span style=&#34;color:#bd93f9&#34;&gt;0&lt;/span&gt;);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Rest parameters allow us to capture a varying-length group of arguments and read them as a real array with a meaningful name we choose. Because it captures a varying-length list of arguments, rest parameters must be the final parameter defined for a function, but they don&amp;rsquo;t have to be the first.  You can define a few static parameters and leave a rest parameter to capture the remainder.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; createBlogPost &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; (name, date, ...tags) =&amp;gt; ({
    id&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; uuid(),
    name,
    metadata&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; {
        date,
        tags,
    },
});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Rest parameters can do everything arguments do&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;, but they do it in a less magic way, without the confusion of managing a fake array.  At this point arguments should be considered an anti-pattern.&lt;/p&gt;
&lt;h4 id=&#34;using-slice-to-convert-something-to-an-array&#34;&gt;Using slice to convert something to an array&lt;/h4&gt;
&lt;p&gt;The previous snippet contained an extra outdated practice.  Did you notice this line?&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; args &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;Array&lt;/span&gt;.prototype.slice.call(arguments);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That was previously the best way to handle fake arrays like &lt;code&gt;arguments&lt;/code&gt;, NodeLists, or just &lt;code&gt;{3: 1, length: 4}&lt;/code&gt;. &lt;code&gt;slice&lt;/code&gt; makes a copy of an array, optionally adding or deleting elements.  Here we&amp;rsquo;re only passing &lt;code&gt;arguments&lt;/code&gt; as the &lt;code&gt;this&lt;/code&gt; value of the function, so it works the same as &lt;code&gt;arr.slice()&lt;/code&gt;.  When called without arguments, &lt;code&gt;slice&lt;/code&gt; is essentially a clone function.  But this code looks pretty bizarre if you haven&amp;rsquo;t seen it before.  It also slides into the &amp;ldquo;wait did I mean slice or splice?&amp;rdquo; vortex of array method confusion. So it isn&amp;rsquo;t a particularly readable solution.&lt;/p&gt;
&lt;p&gt;ES6 introduced the &lt;code&gt;Array.from&lt;/code&gt; method to improve this situation.  &lt;code&gt;Array.from&lt;/code&gt; takes an array-like object and creates a real array copy of it.  So it can be a clone method for existing arrays, or a conversion method for fakes like &lt;code&gt;arguments&lt;/code&gt;.  &lt;code&gt;Array.from(arguments)&lt;/code&gt; certainly reads a lot cleaner than the slice method.  It should be noted that they aren&amp;rsquo;t completely equivalent.  &lt;code&gt;slice&lt;/code&gt; will leave missing indices as holes, while &lt;code&gt;Array.from&lt;/code&gt; will add those indices and set them to undefined.  So you can see the following difference&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; fakeArray &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {&lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;3&lt;/span&gt;, &lt;span style=&#34;color:#bd93f9&#34;&gt;3&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;5&lt;/span&gt;, length&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;4&lt;/span&gt;};

&lt;span style=&#34;color:#6272a4&#34;&gt;// convert object to a real array
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; slicedArray &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;Array&lt;/span&gt;.prototype.slice.call(fakeArray);
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; frommedArray &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;Array&lt;/span&gt;.from(fakeArray);

&lt;span style=&#34;color:#6272a4&#34;&gt;// filter Out 5s
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; slicedArrayNoFives &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; slicedArray.filter(x =&amp;gt; x &lt;span style=&#34;color:#ff79c6&#34;&gt;!==&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;5&lt;/span&gt;);
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; frommedArrayNoFives &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; frommedArray.filter(x =&amp;gt; x &lt;span style=&#34;color:#ff79c6&#34;&gt;!==&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;5&lt;/span&gt;);

console.log(slicedArrayNoFives) &lt;span style=&#34;color:#6272a4&#34;&gt;// [3]
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;console.log(frommedArrayNoFives) &lt;span style=&#34;color:#6272a4&#34;&gt;// [undefined, 3, undefined]
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You can see my &lt;a href=&#34;https://benmccormick.org/2018/06/19/code-golf-sparse-arrays/&#34;&gt;last post&lt;/a&gt; for more on holes in arrays.&lt;/p&gt;
&lt;h3 id=&#34;moving-forward&#34;&gt;Moving Forward&lt;/h3&gt;
&lt;p&gt;The fun of this industry is that everything is always changing.  The frustration of this industry is that everything is always changing.  I&amp;rsquo;m sure ES2020 or whatever they call it by then will give us plenty of new &amp;ldquo;best practices&amp;rdquo;.  In the meantime, no need to throw away all your code right away.  But if you&amp;rsquo;re setting an example for others, it would be a great time to update some visible examples of stale practices to point to the newer, more friendly solutions.  Even if you don&amp;rsquo;t have your own blog posts or documentation to change, you can update public documentation.  Did you know that anyone can update the MDN JavaScript documentation?  I was able to add information about module strict mode to the &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode&#34;&gt;MDN article&lt;/a&gt; while working on this post.  And you can upvote modern answers to popular old questions on StackOverflow.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://stackoverflow.com/a/960870/1424361&#34;&gt;Using &lt;code&gt;Array.from&lt;/code&gt; to convert &lt;code&gt;arguments&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://stackoverflow.com/a/16661498/1424361&#34;&gt;let instead of closures in loops&lt;/a&gt; &lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Or just do some refactoring of high traffic code in your own code bases, so that older code isn&amp;rsquo;t copy and pasted, and you have good examples of the better way to do things.&lt;/p&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;Ok technically arguments has an &lt;code&gt;arguments.callee&lt;/code&gt; property that gives you a reference to the calling function, but you can recreate this by giving your function a name, and using &lt;code&gt;arguments.callee&lt;/code&gt; is an error in strict mode.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;Yeah&amp;hellip; that one is my answer.  I promise I&amp;rsquo;m not just trolling for upvotes :)&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>Weekly Links: June 23rd</title>
      <link>https://benmccormick.org/2018/06/22/weekly-links-june.html</link>
      <pubDate>Fri, 22 Jun 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/06/23/weekly-links-june.html</guid>
      <description>&lt;h3 id=&#34;javascript--the-web&#34;&gt;JavaScript &amp;amp; The Web&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://www.gatsbyjs.org/blog/2018-06-16-announcing-gatsby-v2-beta-launch/&#34;&gt;Announcing Gatsby v2 beta launch! | GatsbyJS&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Gatsby continues to be one of the most exciting things happening in web development.  If you&amp;rsquo;re unfamiliar, Gatsby is a tool for building performant content-focused sites with React and GraphQL.  This blog has been built on it for the last 18 months or so.  Updating to V2 is pretty straightforward, I&amp;rsquo;ve been running it on here for the past week with no problems.  And V2 offers some nice improvements in terms of hot loading speed, library updates (it&amp;rsquo;s React 16, Babel 7 and Webpack 4 friendly) and API improvements.  It&amp;rsquo;s also obvious that since they &lt;a href=&#34;https://benmccormick.org/2018/05/27/weekly-links-05-27-18/&#34;&gt;announced that Gatsby contributors were forming a company&lt;/a&gt; the docs and marketing materials have been quickly moving from &amp;ldquo;indy open source&amp;rdquo; level to &amp;ldquo;real company&amp;rdquo; level, which is cool to see.&lt;/p&gt;
&lt;h3 id=&#34;programming-practices&#34;&gt;Programming Practices&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;http://laputan.org/mud/&#34;&gt;Big Ball of Mud |  Brian Foote and Joseph Yoder &lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This is an older piece (1999), but a cool reflection on &amp;ldquo;Big Balls of Mud&amp;rdquo;: computer systems that have been designed haphazardly and are now difficult to change.  Besides giving these systems a great name, Foote and Yoder are thoughtful about why these systems come to be, and how and when that may be appropriate.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://amasad.me/intuition&#34;&gt;Overcoming Intuition in Programming&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Some interesting reflections here on how we use frameworks to reduce the cognitively challenging parts of programming.  I can definitely recall feeling less useful outside of my comfort zone when I&amp;rsquo;ve spent too much time working with &amp;ldquo;intuitive&amp;rdquo; code.&lt;/p&gt;
&lt;h3 id=&#34;books&#34;&gt;Books&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://leanpub.com/javascriptallongesix/read&#34;&gt;JavaScript Allongé | Reg Braithwaite&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I realized the other day that I had never written a review of one of my favorite JavaScript books on this site.  This won&amp;rsquo;t count as a full review, but suffice it to say that if you&amp;rsquo;re interested in functional programming, want to get a deeper understanding of JavaScript, or really like JavaScript &lt;strong&gt;and&lt;/strong&gt; coffee, this is the book for you.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://amzn.to/2MiGMSV&#34;&gt;On Writing Well | William Zinsser&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Over the past year, I&amp;rsquo;ve been going through a challenge to read 30 books in a year.  I am well aware of my limitations as a writer, so one of the books I added to the list was &amp;ldquo;On Writing Well&amp;rdquo;, recommended from multiple sources as the best resource for non-fiction writing.&lt;/p&gt;
&lt;p&gt;Reading a 42 year old book&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; about writing is a nice view into what has changed over the last half century and what hasn&amp;rsquo;t.  The basic principles the book lays out are as applicable as ever, however its specific examples often feel a bit dated.  It lacks any direct instruction about the type of writing that now happens in emails, slack and social media&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;, but it pointed me back to a time where our public writing was created with more care and resulted in more eloquence than you usually find in today&amp;rsquo;s frenzied discourse.  Parts of the book felt dated to me, but there was plenty of practical advice to glean, and even more sections I found inspiring.  I finished up wanting my writing to be better and had some practical ideas about how to make that happen.  And I learned a little bit about painting birds and the salt caravans of the Sahara along the way.  What more can you ask for?&lt;/p&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;It was last updated in 2006, so it&amp;rsquo;s not completely that old.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;There is a great opportunity sitting out there for somebody to write the definitive book on modern business writing skills.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>Code Golf: Sparse Arrays</title>
      <link>https://benmccormick.org/2018/06/19/010000.html</link>
      <pubDate>Tue, 19 Jun 2018 02:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/06/19/010000.html</guid>
      <description>&lt;p&gt;Today on Twitter, &lt;a href=&#34;http://2ality.com/index.html&#34;&gt;Axel Rauschmayer&lt;/a&gt; posted a fun little coding challenge:&lt;/p&gt;
&lt;blockquote class=&#34;twitter-tweet&#34; data-lang=&#34;en&#34;&gt;&lt;p lang=&#34;en&#34; dir=&#34;ltr&#34;&gt;Code golf: check if an Array has holes. I’ll reply with two ideas of mine in a few minutes.&lt;/p&gt;&amp;mdash; Axel Rauschmayer (@rauschma) &lt;a href=&#34;https://twitter.com/rauschma/status/1009053456123027463?ref_src=twsrc%5Etfw&#34;&gt;June 19, 2018&lt;/a&gt;&lt;/blockquote&gt;
&lt;p&gt;For context, &lt;em&gt;code golf&lt;/em&gt; is a type of challenge where participants attempt to find the shortest possible way to express a program.  Arrays that have holes, or sparse arrays, refer to arrays that don&amp;rsquo;t have values at every index between their maximum and minimum values.  You can define a sparse array like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; arr &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; [&lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;];
arr[&lt;span style=&#34;color:#bd93f9&#34;&gt;100&lt;/span&gt;] &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt;
&lt;span style=&#34;color:#6272a4&#34;&gt;// arr.length is 100
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;or like this&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; arr &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; [&lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;,,&lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt;];
&lt;span style=&#34;color:#6272a4&#34;&gt;// arr.length is 3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is different from &lt;code&gt;let arr = [1, undefined, 2]&lt;/code&gt;, because the index keys are not defined.  If this is difficult to understand, you can picture arrays as simple objects, with access to the &lt;code&gt;Array.Prototype&lt;/code&gt; methods and a special &lt;code&gt;length&lt;/code&gt; property that is aware of numeric keys.  The important thing is not whether a value is defined for a specific index, but whether a key was ever explicitly set.  Axel&amp;rsquo;s suggested solutions take advantage of that distinction:&lt;/p&gt;
&lt;blockquote class=&#34;twitter-tweet&#34; data-conversation=&#34;none&#34; data-lang=&#34;en&#34;&gt;&lt;p lang=&#34;en&#34; dir=&#34;ltr&#34;&gt;// Does someArray have holes?&lt;br&gt;&lt;br&gt;someArray.findIndex((x,i,arr) =&amp;gt; x === undefined &amp;amp;&amp;amp; !(i in arr)) &amp;gt;= 0&lt;br&gt;Object.keys(someArray).length &amp;lt; someArray.length&lt;br&gt;someArray.filter(_ =&amp;gt; true).length &amp;lt; someArray.length&lt;/p&gt;&amp;mdash; Axel Rauschmayer (@rauschma) &lt;a href=&#34;https://twitter.com/rauschma/status/1009056501095428096?ref_src=twsrc%5Etfw&#34;&gt;June 19, 2018&lt;/a&gt;&lt;/blockquote&gt;
&lt;p&gt;I&amp;rsquo;m going to standardize these into a function syntax for the purpose of comparison.  I&amp;rsquo;m only going to consider one liners, so we&amp;rsquo;ll define a simple arrow function &lt;code&gt;isSparse&lt;/code&gt;, and compare the length of the function bodies.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;// Solution 1
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; isSparse &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; someArray =&amp;gt; someArray.findIndex((x,i,arr) =&amp;gt; x &lt;span style=&#34;color:#ff79c6&#34;&gt;===&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;undefined&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;!&lt;/span&gt;(i &lt;span style=&#34;color:#ff79c6&#34;&gt;in&lt;/span&gt; arr)) &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;=&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;0&lt;/span&gt;
&lt;span style=&#34;color:#6272a4&#34;&gt;// Solution 1 condensed (49 characters)
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; isSparse &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; a =&amp;gt; a.findIndex((x,i,b)=&amp;gt;x&lt;span style=&#34;color:#ff79c6&#34;&gt;===&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;undefined&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;amp;&amp;amp;!&lt;/span&gt;(i &lt;span style=&#34;color:#ff79c6&#34;&gt;in&lt;/span&gt; b))&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;=&lt;/span&gt;&lt;span style=&#34;color:#bd93f9&#34;&gt;0&lt;/span&gt;
&lt;span style=&#34;color:#6272a4&#34;&gt;// Solution 2
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; isSparse &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; someArray =&amp;gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;Object&lt;/span&gt;.keys(someArray).length &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt; someArray.length
&lt;span style=&#34;color:#6272a4&#34;&gt;// Solution 2 condensed (30 characters)
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; isSparse &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; a =&amp;gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;Object&lt;/span&gt;.keys(a).length&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;a.length
&lt;span style=&#34;color:#6272a4&#34;&gt;// Solution 3
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; isSparse &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; someArray =&amp;gt; someArray.filter(_ =&amp;gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;true&lt;/span&gt;).length &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt; someArray.length
&lt;span style=&#34;color:#6272a4&#34;&gt;// Solution 3 condensed (33 characters)
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; isSparse &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; a =&amp;gt; a.filter(_=&amp;gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;true&lt;/span&gt;).length&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;a.length
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Axel&amp;rsquo;s solutions all rely on the fact that sparse items don&amp;rsquo;t have keys, and that Object.keys and Array.prototype methods therefore don&amp;rsquo;t iterate over them.  That&amp;rsquo;s a good insight and a good foundation for getting even more concise.  We can use a few tricks to do that.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s start with his second solution, which was the shortest and clearest in practice and modify it a bit&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;// We&amp;#39;re comparing the length of the list of keys to the array length
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; isSparse &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; a =&amp;gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;Object&lt;/span&gt;.keys(a).length&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;a.length
&lt;span style=&#34;color:#6272a4&#34;&gt;//But we can use reduce to do this instead (28 characters)
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; isSparse &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; a =&amp;gt; a.reduce(x=&amp;gt;x&lt;span style=&#34;color:#ff79c6&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;,a.length)&lt;span style=&#34;color:#ff79c6&#34;&gt;==&lt;/span&gt;&lt;span style=&#34;color:#bd93f9&#34;&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So our first step is to use &lt;code&gt;reduce&lt;/code&gt; to save 2 characters.  If you haven&amp;rsquo;t seen &lt;code&gt;reduce&lt;/code&gt; before, I recommend checking out &lt;a href=&#34;https://css-tricks.com/understanding-the-almighty-reducer/&#34;&gt;this great explainer&lt;/a&gt; by Sarah Drasner that I linked to in my &lt;a href=&#34;https://benmccormick.org/2018/06/15/weekly-links-06-15-18/&#34;&gt;Weekly Links post&lt;/a&gt; last week.  Essentially though, reduce is a generic method for iterating through an array to produce a new value.  It takes a function and an initial value, and uses the items of the array to iteratively transform the initial value.  In this case, I&amp;rsquo;m just decrementing the value for each defined item in the array, starting at length and seeing if it equals 0.  Which ends up being shorter than taking the length of the keys array.  But we can still do better!&lt;/p&gt;
&lt;p&gt;Our next step will take advantage of a property of numbers in JavaScript.  When converting numbers to booleans, &lt;code&gt;0&lt;/code&gt; is considered &lt;em&gt;falsy&lt;/em&gt;, while every other number is considered &lt;em&gt;truthy&lt;/em&gt;.  Since we want our function to produce a boolean, we can take advantage of this property, and write our function like this.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;// Boolean version (27 characters)
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; isSparse &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; a =&amp;gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;!!&lt;/span&gt;a.reduce(x=&amp;gt;x&lt;span style=&#34;color:#ff79c6&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;,a.length)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That seems like a bit of a local maximum.  But getting to this point made me realize that we weren&amp;rsquo;t actually saving anything by using the boolean version over a comparison, since we can increment instead and end up at the same length.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;// Counting up to length (27 characters)
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; isSparse &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; a =&amp;gt; a.reduce(x=&amp;gt;x&lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt;&lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;,&lt;span style=&#34;color:#bd93f9&#34;&gt;0&lt;/span&gt;)&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;a.length
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;del&gt;Doing it this way though, we can actually save 2 more characters, because if reduce doesn&amp;rsquo;t have an initial value, it just uses the unmodified first element in an array as its initial value, and goes from there:&lt;/del&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;// Final (broken) Version (25 characters)
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;// UPDATE: This doesn&amp;#39;t work
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; isSparse &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; a =&amp;gt; a.reduce(x=&amp;gt;x&lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt;&lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;)&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;a.length
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Update: This last solution only works in situations where the array starts with &lt;code&gt;1&lt;/code&gt;.  So 27 is the best generic solution I can find at this point.  Thanks to &lt;a href=&#34;https://twitter.com/rauschma/status/1009149034622275585&#34;&gt;Axel&lt;/a&gt; for correcting me. Code golf is hard 😔.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;So there you have it.  27 characters to identify sparse arrays.  I&amp;rsquo;d love to hear from you if you can do better.  Hit me up on &lt;a href=&#34;https://twitter.com/_benmccormick&#34;&gt;Twitter&lt;/a&gt; or by &lt;a href=&#34;ben@benmccormick.org&#34;&gt;email&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>A Codemod Survival Guide</title>
      <link>https://benmccormick.org/2018/06/17/190000.html</link>
      <pubDate>Sun, 17 Jun 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/06/18/190000.html</guid>
      <description>&lt;p&gt;Do you like making repetitive syntax updates across many files?  Enjoy the thrill of painstakingly combing through 1000 line diffs that all look the same to see if you made any typos?  Relish that feeling of doubt in the back of your head as you wonder whether you actually caught all instances of the syntax you needed to update when you switched to the next major version of a library?  If so, you should probably stop reading now, because you won&amp;rsquo;t like codemods at all.  For the rest of us, codemods are a tool for assisting in large refactoring; they save you time and reduce typos.&lt;/p&gt;
&lt;p&gt;Codemods originated at Facebook, first with a tool named &lt;a href=&#34;https://github.com/facebook/codemod&#34;&gt;codemod&lt;/a&gt; that served as a helper for regex or python based refactoring, allowing you to make iterative changes with pretty diffs, then with &lt;a href=&#34;https://github.com/facebook/jscodeshift&#34;&gt;jscodeshift&lt;/a&gt; a tool for doing more advanced JavaScript refactors that work directly against a data model representation of the code, rather than relying on regex or direct programmatic changes to text.  jscodeshift is extremely powerful, but I found it intimidating to approach.  Once I took the plunge though, it wasn&amp;rsquo;t that hard to start writing codemods.  So here are a few quick tips for anyone else who might be interested.&lt;/p&gt;
&lt;h4 id=&#34;1-start-with-a-goal-in-mind&#34;&gt;1. Start with a goal in mind&lt;/h4&gt;
&lt;p&gt;It&amp;rsquo;s always helpful to dive into a new technology by trying to solve a concrete problem.  That&amp;rsquo;s especially useful for codemods, because the ideas behind them can seem abstract and poorly documented until you begin focusing on a specific issue.  In my case I was originally motivated to look at codemods when updating an application from using MobX version 3 to MobX version 5.  In MobX3, when you write code without using decorators, a typical model class will look something like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; { extendObservable, computed, action} from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;mobx&amp;#39;&lt;/span&gt;;

&lt;span style=&#34;color:#ff79c6&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; Example {
    constructor() {
        extendObservable(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;, {
            foo&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;false&lt;/span&gt;,
            bar&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;false&lt;/span&gt;,
            currentData&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; computed(() =&amp;gt; {
                &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; foo &lt;span style=&#34;color:#ff79c6&#34;&gt;||&lt;/span&gt; bar;
            }),
            otherData&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; computed(() =&amp;gt; foo &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; bar),
            setFoo&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; action(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Set Foo&amp;#39;&lt;/span&gt;, val =&amp;gt; {
                &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.foo &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; val;
            }),
            setBar&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; action(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Set Bar&amp;#39;&lt;/span&gt;, val =&amp;gt; {
                &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.bar &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; val;
            }),

        });
    }

    unrelatedMethod(key) {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; key;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I was updating an app with dozens of these model classes.  Unfortunately, in Mobx5, the syntax for these classes has changed, and it now needs to be rewritten like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; { extendObservable, action} from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;mobx&amp;#39;&lt;/span&gt;;

&lt;span style=&#34;color:#ff79c6&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; Example {
    constructor() {
        extendObservable(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;, {
            foo&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;false&lt;/span&gt;,
            bar&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;false&lt;/span&gt;,
            get currentData() {
                &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; foo &lt;span style=&#34;color:#ff79c6&#34;&gt;||&lt;/span&gt; bar;
            },
            get otherData() {
                &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; foo &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; bar;
            },
            setFoo&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; val =&amp;gt; {
                &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.foo &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; val;
            },
            setBar&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; val =&amp;gt; {
                &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.bar &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; val;
            },

        }, {
            setFoo&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; action(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Set Foo&amp;#39;&lt;/span&gt;),
            setBar&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; action(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Set Bar&amp;#39;&lt;/span&gt;)
        });
    }

    unrelatedMethod(key) {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; key;
    }
}

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Computeds must be shifted to gets, action functions have to be pulled out of their wrapper function calls, but the wrapper and action names have to be moved down to a new second object.  This is really finicky to do by hand or with a text editor macro, because it&amp;rsquo;s a lot more complicated than just find and replace.  I&amp;rsquo;d usually be converting from arrow functions that might or might not have blocks and return statements currently, and I&amp;rsquo;d have to move the actions down to the new object correctly even though some of the models had 10+ action functions.   Facing several hours worth of finicky manual or script assisted refactoring work was enough to convince me it was time to learn about codemods.&lt;/p&gt;
&lt;h4 id=&#34;2-create-a-small-example-and-learn-about-its-ast&#34;&gt;2. Create a small example and learn about its AST&lt;/h4&gt;
&lt;p&gt;My first productive step towards creating a Mobx3to5 codemod for my codebase was creating the example code above.  I iterated on it a bit as I found new things I cared about; I didn&amp;rsquo;t realize at first that computeds needed to be changed as well as actions, and I eventually realized I needed to handle 2 types of arrow function syntax. But the initial version I wrote got me going.  Having a stripped down example of the code I cared about without the baggage of my real codebase was valuable, and being able to update it to include all the cases I cared about during testing was even better.&lt;/p&gt;
&lt;p&gt;Once I created the example, I was able to understand better what I was trying to do by examining its AST.  An AST (Abstract Syntax Tree) is a representation of a JavaScript file&amp;rsquo;s source code as a tree data structure.  For instance here&amp;rsquo;s a portion of the AST for a basic Hello World program:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;{
  &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;Program&amp;#34;&lt;/span&gt;,
  &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;sourceType&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;module&amp;#34;&lt;/span&gt;,
  &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;body&amp;#34;&lt;/span&gt;: [
    {
      &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;ExpressionStatement&amp;#34;&lt;/span&gt;,
      &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;expression&amp;#34;&lt;/span&gt;: {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;CallExpression&amp;#34;&lt;/span&gt;,
        &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;callee&amp;#34;&lt;/span&gt;: {
          &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;MemberExpression&amp;#34;&lt;/span&gt;,
          &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;object&amp;#34;&lt;/span&gt;: {
            &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;Identifier&amp;#34;&lt;/span&gt;,
            &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;console&amp;#34;&lt;/span&gt;,
            &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;_babelType&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;Identifier&amp;#34;&lt;/span&gt;
          },
          &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;property&amp;#34;&lt;/span&gt;: {
            &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;Identifier&amp;#34;&lt;/span&gt;,
            &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;log&amp;#34;&lt;/span&gt;,
            &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;_babelType&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;Identifier&amp;#34;&lt;/span&gt;
          },
          &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;computed&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ff79c6&#34;&gt;false&lt;/span&gt;,
          &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;_babelType&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;MemberExpression&amp;#34;&lt;/span&gt;
        },
        &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;arguments&amp;#34;&lt;/span&gt;: [
          {
            &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;Literal&amp;#34;&lt;/span&gt;,
            &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;value&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;Hello World&amp;#34;&lt;/span&gt;,
            &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;rawValue&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;Hello World&amp;#34;&lt;/span&gt;,
            &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;raw&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;&amp;#39;Hello World&amp;#39;&amp;#34;&lt;/span&gt;,
            &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;_babelType&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;Literal&amp;#34;&lt;/span&gt;
          }
        ],
        &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;_babelType&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;CallExpression&amp;#34;&lt;/span&gt;
      },
      &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;_babelType&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;ExpressionStatement&amp;#34;&lt;/span&gt;
    }
  ],
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is a simplified example that looks only at the semantic structure of the syntax.  The full version also contains information about the indenting and exact text of the code, and comes out to about 600 lines when represented as formatted JSON.   All of this from &lt;code&gt;console.log(&#39;Hello World&#39;);&lt;/code&gt;.  Fortunately there&amp;rsquo;s a nice tool for exploring ASTs.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://astexplorer.net/&#34;&gt;AST Explorer&lt;/a&gt; is a site that lets you enter some JavaScript code, and then visualize the AST that represents the code.  When I put my example code above, in, I was able to see that the computed expressions in my original code showed as a &lt;code&gt;CallExpression&lt;/code&gt; with an &lt;code&gt;ArrowFunctionExpression&lt;/code&gt; as an argument.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;computed-ast.png&#34; alt=&#34;AST explorer screenshot showing the CallExpression syntax&#34;&gt;&lt;/p&gt;
&lt;p&gt;When I put the result code I wanted in, I could see that I would need to switch the property that contained the callexpression to have a type &lt;code&gt;get&lt;/code&gt; and would need to replace the call expression with a function expression.&lt;/p&gt;
&lt;h4 id=&#34;3-start-with-a-small-edit&#34;&gt;3. Start with a small edit&lt;/h4&gt;
&lt;p&gt;As a starting point, I decided I wanted to write a script that could find MobX classes and just add the second object argument to extendObservable, with a dummy property.  So this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;extendObservable(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;, {
    foo&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;false&lt;/span&gt;,
    bar&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;false&lt;/span&gt;,
    currentData&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; computed(() =&amp;gt; {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; foo &lt;span style=&#34;color:#ff79c6&#34;&gt;||&lt;/span&gt; bar;
    }),
    otherData&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; computed(() =&amp;gt; foo &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; bar),
    setFoo&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; action(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Set Foo&amp;#39;&lt;/span&gt;, val =&amp;gt; {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.foo &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; val;
    }),
    setBar&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; action(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Set Bar&amp;#39;&lt;/span&gt;, val =&amp;gt; {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.bar &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; val;
    }),

});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;would become this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;extendObservable(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;, {
    foo&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;false&lt;/span&gt;,
    bar&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;false&lt;/span&gt;,
    currentData&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; computed(() =&amp;gt; {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; foo &lt;span style=&#34;color:#ff79c6&#34;&gt;||&lt;/span&gt; bar;
    }),
    otherData&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; computed(() =&amp;gt; foo &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; bar),
    setFoo&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; action(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Set Foo&amp;#39;&lt;/span&gt;, val =&amp;gt; {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.foo &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; val;
    }),
    setBar&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; action(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Set Bar&amp;#39;&lt;/span&gt;, val =&amp;gt; {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.bar &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; val;
    }),

}, { foo&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To do this, I took an existing script that I found in &lt;a href=&#34;https://github.com/jhgg/js-transforms&#34;&gt;this repo of small codemod examples&lt;/a&gt; and modified it to lookup &lt;code&gt;extendObservable&lt;/code&gt; calls and add a second argument.  I filtered it to only include calls with 2 arguments, in case I ran the code a second time&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;module.exports &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt; (file, api) {
    &lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; j &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; api.jscodeshift;

    &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; j(file.source)
        &lt;span style=&#34;color:#6272a4&#34;&gt;// We&amp;#39;re looking for a CallExpression for extend observable
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;        .find(j.CallExpression, {
            callee&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; {
                name&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;extendObservable&amp;#39;&lt;/span&gt;
            }
        })
        &lt;span style=&#34;color:#6272a4&#34;&gt;// Verify that it&amp;#39;s only using 2 arguments so far, and that the second one is an Object Expression
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;        .filter(p =&amp;gt; p.value.arguments.length &lt;span style=&#34;color:#ff79c6&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; p.value.arguments[&lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;].type &lt;span style=&#34;color:#ff79c6&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;ObjectExpression&amp;#34;&lt;/span&gt;)
        .forEach(p =&amp;gt; {
            &lt;span style=&#34;color:#6272a4&#34;&gt;// Now we want to
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;            &lt;span style=&#34;color:#6272a4&#34;&gt;// 1. Add a 3rd argument object
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;            &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; args &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; p.value.arguments;
            args.push(j.objectExpression([j.property(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;init&amp;#39;&lt;/span&gt;,j.identifier(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;), j.literal(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;))]));
            &lt;span style=&#34;color:#6272a4&#34;&gt;// TODO: 2. Move action declarations to that argument
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;            &lt;span style=&#34;color:#6272a4&#34;&gt;// TODO: 3. Convert action statements to plain functions
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;            &lt;span style=&#34;color:#6272a4&#34;&gt;// TODO: 4. Convert computeds to get statements
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;        })
        .toSource();
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is a working script to achieve my simple goal.  To break it down:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;j(file.source).find(j.CallExpression, {
            callee&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; {
                name&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;extendObservable&amp;#39;&lt;/span&gt;
            }
        })
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;jscodeshift provides a jQuery style api for traversing a tree.  Here we&amp;rsquo;re looking for &lt;code&gt;CallExpression&lt;/code&gt;s that have the name &lt;code&gt;extendObservable&lt;/code&gt;.  We now have a collection of these expressions, and we can filter it down to only the expressions that have 2 arguments.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;.filter(p =&amp;gt; p.value.arguments.length &lt;span style=&#34;color:#ff79c6&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; p.value.arguments[&lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;].type &lt;span style=&#34;color:#ff79c6&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;ObjectExpression&amp;#34;&lt;/span&gt;)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Next we want to go through each callExpression and transform it.  In this case by finding it&amp;rsquo;s arguments list and pushing a new one, using the jsCodeshift API to simply generate the AST objects neededed to represent &lt;code&gt;{foo: bar}&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;.forEach(p =&amp;gt; {
            &lt;span style=&#34;color:#6272a4&#34;&gt;// Now we want to
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;            &lt;span style=&#34;color:#6272a4&#34;&gt;// 1. Add a 3rd argument object
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;            &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; args &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; p.value.arguments;
            args.push(j.objectExpression([j.property(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;init&amp;#39;&lt;/span&gt;,j.identifier(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;), j.literal(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;))]));
            &lt;span style=&#34;color:#6272a4&#34;&gt;// TODO: 2. Move action declarations to that argument
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;            &lt;span style=&#34;color:#6272a4&#34;&gt;// TODO: 3. Convert action statements to plain functions
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;            &lt;span style=&#34;color:#6272a4&#34;&gt;// TODO: 4. Convert computeds to get statements
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;        })
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Finally, we call &lt;code&gt;.toSource()&lt;/code&gt; to write the tranformed AST back to the file.&lt;/p&gt;
&lt;h4 id=&#34;4-test-your-edit&#34;&gt;4. Test your edit&lt;/h4&gt;
&lt;p&gt;Because this type of coding lends itself to experimentation, it&amp;rsquo;s important to develop a good feedback loop while working on your codemod.  If you have a simple example you&amp;rsquo;re off to a good start.  The next step is to find a good way to run your script and see the output.  Simply running your test is a bit frustrating, because jscodeshift is destructive.  It overwrites your file in place, and doesn&amp;rsquo;t save a copy.  You can get around this though by adding &lt;code&gt;--dry --print&lt;/code&gt; flags to your command line call&lt;/p&gt;
&lt;p&gt;&lt;code&gt;jscodeshift -t my-codemod.js example.js&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;will run the transform defined in &lt;code&gt;my-codemod.js&lt;/code&gt; against &lt;code&gt;example.js&lt;/code&gt; and modify it in place.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;jscodeshift --dry --print -t my-codemod.js example.js&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;will print the transformed file to the console and not update example.js.&lt;/p&gt;
&lt;p&gt;For simple codemods and small example files, this is a nice way to iterate quickly.  For more extensive codemods with multiple test cases, I&amp;rsquo;m excited to try out jscodeshift&amp;rsquo;s Jest support&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;.  It has helper methods for working with transforms, and a workflow of Jest watch checking the output of several inputs against several expected outputs would be lovely.&lt;/p&gt;
&lt;h4 id=&#34;5-iterate&#34;&gt;5. Iterate&lt;/h4&gt;
&lt;p&gt;After I got that first edit working, it was simply a matter of working through my list.  I needed to remove the experimental &lt;code&gt;foo:bar&lt;/code&gt; and then&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Move action declarations to the new argument object&lt;/li&gt;
&lt;li&gt;Convert action declarations to plain functions in the existing object&lt;/li&gt;
&lt;li&gt;Convert computeds to get statements&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I was able to take those one at a time, and my final script looked something like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;module.exports &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt; (file, api) {
    &lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; j &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; api.jscodeshift;

    &lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; buildDecoratorPropertiesFromCurrentObject &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; currentObj =&amp;gt; {

        &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; decoratorProps &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; [];
        currentObj.properties.forEach(prop =&amp;gt; {
            &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (prop.value.type &lt;span style=&#34;color:#ff79c6&#34;&gt;===&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;CallExpression&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; prop.value.callee.name &lt;span style=&#34;color:#ff79c6&#34;&gt;===&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;computed&amp;#39;&lt;/span&gt;) {
                prop.kind &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;get&amp;#39;&lt;/span&gt;;
                &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; fnBody &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; prop.value.arguments[&lt;span style=&#34;color:#bd93f9&#34;&gt;0&lt;/span&gt;];
                &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (fnBody.type &lt;span style=&#34;color:#ff79c6&#34;&gt;===&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;ArrowFunctionExpression&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; fnBody.body.type &lt;span style=&#34;color:#ff79c6&#34;&gt;!==&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;BlockStatement&amp;#39;&lt;/span&gt;) {
                    prop.value &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; j.functionExpression(&lt;span style=&#34;color:#ff79c6&#34;&gt;null&lt;/span&gt;, fnBody.params,
                        j.blockStatement([j.returnStatement(fnBody.body)]),
                        &lt;span style=&#34;color:#ff79c6&#34;&gt;false&lt;/span&gt;);
                } &lt;span style=&#34;color:#ff79c6&#34;&gt;else&lt;/span&gt; {
                    prop.value &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; j.functionExpression(&lt;span style=&#34;color:#ff79c6&#34;&gt;null&lt;/span&gt;, fnBody.params, fnBody.body, &lt;span style=&#34;color:#ff79c6&#34;&gt;false&lt;/span&gt;);
                }
            }
        });
        &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; dataProps &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; currentObj.properties.filter(prop =&amp;gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;!&lt;/span&gt;(prop.value.type &lt;span style=&#34;color:#ff79c6&#34;&gt;===&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;CallExpression&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; prop.value.callee.name &lt;span style=&#34;color:#ff79c6&#34;&gt;===&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;computed&amp;#39;&lt;/span&gt;));
        dataProps.forEach(prop =&amp;gt; {
            &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (prop.value.type &lt;span style=&#34;color:#ff79c6&#34;&gt;===&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;CallExpression&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; prop.value.callee.name &lt;span style=&#34;color:#ff79c6&#34;&gt;===&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;action&amp;#39;&lt;/span&gt;) {
                &lt;span style=&#34;color:#6272a4&#34;&gt;// copy action to the decorator area first...
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;                &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; args &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; prop.value.arguments;
                &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; dupProp &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;Object&lt;/span&gt;.assign({}, prop);
                dupProp.value &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;Object&lt;/span&gt;.assign({}, dupProp.value);
                dupProp.value.arguments &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; (args.length &lt;span style=&#34;color:#ff79c6&#34;&gt;===&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt;) &lt;span style=&#34;color:#ff79c6&#34;&gt;?&lt;/span&gt; args.slice(&lt;span style=&#34;color:#bd93f9&#34;&gt;0&lt;/span&gt;, &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;) &lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; [];
                decoratorProps.push(dupProp);

                &lt;span style=&#34;color:#6272a4&#34;&gt;// then flatten things out
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;                prop.value &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; (args.length &lt;span style=&#34;color:#ff79c6&#34;&gt;===&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt;) &lt;span style=&#34;color:#ff79c6&#34;&gt;?&lt;/span&gt; args[&lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;] &lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; args[&lt;span style=&#34;color:#bd93f9&#34;&gt;0&lt;/span&gt;];
            }
        });
        &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; [dataProps, decoratorProps];
    }
    &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; j(file.source)
        &lt;span style=&#34;color:#6272a4&#34;&gt;// We&amp;#39;re looking for a CallExpression for extend observable
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;        .find(j.CallExpression, {
            callee&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; {
                name&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;extendObservable&amp;#39;&lt;/span&gt;
            }
        })
        &lt;span style=&#34;color:#6272a4&#34;&gt;// Verify that it&amp;#39;s only using 2 arguments so far, and that the second one is an Object Expression
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;        .filter(p =&amp;gt; p.value.arguments.length &lt;span style=&#34;color:#ff79c6&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; p.value.arguments[&lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;].type &lt;span style=&#34;color:#ff79c6&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;ObjectExpression&amp;#34;&lt;/span&gt;)
        .forEach(p =&amp;gt; {
            &lt;span style=&#34;color:#6272a4&#34;&gt;// Now we want to
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;            &lt;span style=&#34;color:#6272a4&#34;&gt;// 1. Add a 3rd argument
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;            &lt;span style=&#34;color:#6272a4&#34;&gt;// 2. Move action declarations to that argument
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;            &lt;span style=&#34;color:#6272a4&#34;&gt;// 3. Convert action statements to plain functions
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;            &lt;span style=&#34;color:#6272a4&#34;&gt;// 4. Convert computeds to get statements, or just move them down to the second object?
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;            &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; args &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; p.value.arguments;
            &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; [dataProps, decoratorProps] &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; buildDecoratorPropertiesFromCurrentObject(args[&lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;]);
            args[&lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;].properties &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; dataProps;
            args.push(j.objectExpression(decoratorProps));
        })
        .toSource();
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That looks rather crazy, but the &lt;code&gt;buildDecoratorPropertiesFromCurrentObject&lt;/code&gt; is mostly straightforward data manipulation, looking for some patterns in the data, and replacing them with a different pattern.  Everything else is just the same base code from our initial example.&lt;/p&gt;
&lt;h4 id=&#34;6-use-version-control-and-code-reviews&#34;&gt;6. Use version control and code reviews!&lt;/h4&gt;
&lt;p&gt;Actually running a finished transform against a codebase is crazy easy.  Just give it a base folder, and &lt;code&gt;jscodeshift&lt;/code&gt; will run your script against all JavaScript files in the directory.  This is definitely a &amp;ldquo;With great power comes great responsibility&amp;rdquo; tool though.  Before running jscodeshift across a large code base, make sure you are using version control and that you&amp;rsquo;ve checked in any other changes.  Because the script will update many files at once, you want to be able to isolate the change and review it carefully afterwards, to make sure that you see what is different, and that those changes look right.  In my case, I got to be &lt;em&gt;done&lt;/em&gt; with my script twice, because the first time I thought it was ready to execute across all of the app files, things still went wrong.  It was easy to fix though, since I was able to just checkout my changes and try again.&lt;/p&gt;
&lt;h3 id=&#34;resources&#34;&gt;Resources&lt;/h3&gt;
&lt;p&gt;If you have a change that you want to make to your codebase, but have been holding off because you think it would take forever, I definitely encourage you to check codemods out.  They&amp;rsquo;re not as scary as you think!  Here are some more resources to get started:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/facebook/jscodeshift&#34;&gt;facebook/jscodeshift&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://astexplorer.net/&#34;&gt;AST Explorer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://medium.com/@andrew_levine/writing-your-very-first-codemod-with-jscodeshift-7a24c4ede31b&#34;&gt;Writing Your First codemod with jscodeshift&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://medium.com/@cpojer/effective-javascript-codemods-5a6686bb46fb&#34;&gt;Effective JavaScript Codemods&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;This is one of many assumptions I made that won&amp;rsquo;t be true for MobX classes generally.  I was writing a script to convert my app to MobX5 compatible syntax, not write a general case update tool.  In the end there were a few examples that violated my assumptions in the codebase, and I had to update 2 files by hand.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;jscodeshift was created by Christoph Pojer who is also one of the primary maintainers of Jest.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>Weekly Links: June 15th</title>
      <link>https://benmccormick.org/2018/06/14/weekly-links-june.html</link>
      <pubDate>Thu, 14 Jun 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/06/15/weekly-links-june.html</guid>
      <description>&lt;h3 id=&#34;javascript--the-web&#34;&gt;JavaScript &amp;amp; The Web&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://www.graphqlstack.com&#34;&gt;GraphQL Stack&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This is a nice overview of the technologies involved with GraphQL, for anyone who has heard of the technology but isn&amp;rsquo;t quite sure how it all fits together.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://css-tricks.com/understanding-the-almighty-reducer/&#34;&gt;Understanding The Almighty Reducer | Sarah Drasner&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Moving from a loop mindset to making proper use of forEach/map/filter/reduce was one of the biggest shifts I made when moving from Java development to JavaScript.  Reduce especially can be hard to learn initially, and it never becomes simple.  This is a great introduction for those who are unfamiliar or haven&amp;rsquo;t gotten comfortable with writing reducers yet.&lt;/p&gt;
&lt;h3 id=&#34;software--business&#34;&gt;Software + Business&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://seths.blog/2018/06/on-paying-for-software/&#34;&gt;On paying for software | Seth Godin&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This mirrors my opinions on paying for software pretty well.  There&amp;rsquo;s a place in the world for free apps, and I definitely have passed on apps because of price before.  But the apps I&amp;rsquo;ve used that have had real value to me have almost always been paid, usually these days as an ongoing subscription.  The exceptions, like Twitter, tend to come with frustrating downsides that are difficult to disentangle from the free-to-play model.&lt;/p&gt;
&lt;h3 id=&#34;tech-world&#34;&gt;Tech World&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://www.theatlantic.com/science/archive/2018/06/its-possible-to-reverse-climate-change-suggests-major-new-study/562289/&#34;&gt;Climate Change Can Be Reversed by Turning Air Into Gasoline | The Atlantic&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This seems really promising.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://weblog.rogueamoeba.com/2018/06/14/on-the-sad-state-of-macintosh-hardware/&#34;&gt;On The Sad State of Macintosh Hardware | Rogue Amoeba&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m lucky enough to have access to 2 2015 era Macbook Pros (1 for home, 1 for work) and they&amp;rsquo;re amazing machines.  I&amp;rsquo;m hoping that they both have long lifespans. But I&amp;rsquo;m increasingly not sure what my next laptop will be whenever I next have a choice.  It seems like the laptops since then have lost some things I appreciate about my current laptops (Magsafe charger, HDMI port) and made the keyboard significantly worse, with minimum benefits.  I hope that Apple can right this ship.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Weekly Links: June 10th</title>
      <link>https://benmccormick.org/2018/06/09/weekly-links-june.html</link>
      <pubDate>Sat, 09 Jun 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/06/10/weekly-links-june.html</guid>
      <description>&lt;h3 id=&#34;javascript--the-web&#34;&gt;JavaScript &amp;amp; The Web&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://daverupert.com/2018/06/the-react-is-just-javascript-myth/&#34;&gt;The React is “just” JavaScript Myth | Dave Rupert&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve been thinking a lot about the reasons that JavaScript development is perceived as intimidating and over-complicated the past few weeks.  Might have a full post on that soon, but for now, there&amp;rsquo;s a good point here.&lt;/p&gt;
&lt;p&gt;React is relatively simple at it&amp;rsquo;s core, but it&amp;rsquo;s difficult to find examples of using it in the wild, that don&amp;rsquo;t require you to learn Webpack/Babel/npm at minimum, and many &amp;ldquo;starting points&amp;rdquo; will also toss in Redux/React Router/Jest/etc as well.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://medium.com/@mweststrate/mobx-5-the-saga-continues-4852bce05572&#34;&gt;MobX 5: the saga continues… | Michael Weststrate&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;MobX is the first major library I&amp;rsquo;ve seen to take advantage of proxies to give normal looking JavaScript objects/arrays magic powers&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.  This sort of &amp;ldquo;just make it work in the prettiest way possible&amp;rdquo; API is the type of thing that tends to produce really cool results as long as it works correctly 100% of the time, but becomes a huge pain as soon as it&amp;rsquo;s flaky.  I&amp;rsquo;ve never had any problems with MobX after using it for 2 years, so I&amp;rsquo;m hopeful seeing them as an early adapter here.  Will be interested to see if they start getting used more widely going forward.  If so, I hope that browser start thinking about how they can expose these types of patterns well in developer tools.  How do you drop into a side effect caused by a proxy in a debugger?  It&amp;rsquo;s an interesting problem&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://2ality.com/2014/12/es6-proxies.html&#34;&gt;Meta programming with ECMAScript 6 proxies | 2ality&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In case I lost anybody with my discussion of the last link, here&amp;rsquo;s an old but good walkthrough of what Proxies are and how you can use them to create some pretty magical APIs.&lt;/p&gt;
&lt;h3 id=&#34;microsoft-buying-github&#34;&gt;Microsoft Buying Github&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://changelog.com/spotlight/14&#34;&gt;🔥 Our reactions to Microsoft buying GitHub |Adam Stacoviak &amp;amp; Jerod Santo&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A &lt;a href=&#34;https://changelog.com/&#34;&gt;Changelog&lt;/a&gt; podcast that summarizes the reaction of the 2 primary Changelog hosts to the annoucement as well as collecting reactions from around the internet.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/martenbjork/github-xp&#34;&gt;github-xp | Mårten Björk&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This is just fun.  A Chrome extension to render Github in the style of Windows XP.&lt;/p&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;Even if they chose to announce that in the silliest way possible&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>ES6: The Bad Parts</title>
      <link>https://benmccormick.org/2018/06/04/190000.html</link>
      <pubDate>Mon, 04 Jun 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/06/05/190000.html</guid>
      <description>&lt;p&gt;This month is the 3 year anniversary of the ECMAScript2015 spec, &lt;a href=&#34;https://benmccormick.org/2015/09/14/es5-es6-es2016-es-next-whats-going-on-with-javascript-versioning&#34;&gt;better known as ES6&lt;/a&gt;.  It was a spec update that brought a ton of features to the JavaScript language, and the start of a new era of improving the language.  It was also the last &amp;ldquo;big bang&amp;rdquo; release of JavaScript, as TC39 has now moved to a pattern of annual small releases rather than making large multi-year language releases.&lt;/p&gt;
&lt;p&gt;There has been a boatload of justified hype around ES6 over the last 4 years.  I&amp;rsquo;ve been writing all of my code using the modern spec during that time&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;. So this is a good time to step back and evaluate the features that were added.  Specifically there are some features that I used for a while that I&amp;rsquo;ve stopped using, because they made my code worse.&lt;/p&gt;
&lt;p&gt;In his book &lt;a href=&#34;https://amzn.to/2LJBY9z&#34;&gt;JavaScript: The Good Parts&lt;/a&gt; Douglas Crockford dedicated a chapter to the &lt;em&gt;Bad Parts&lt;/em&gt; of JavaScript.  &lt;em&gt;The Bad Parts&lt;/em&gt; are the features of JavaScript that he felt shouldn&amp;rsquo;t be used.  Fortunately there is nothing as bad in ES6 as some of the old JavaScript stinkers like coercive equality, eval or the &lt;code&gt;with&lt;/code&gt; statement.  ES6 was a well-designed release. But there are some features and patterns that I avoid. A JavaScript feature makes my &lt;em&gt;Bad Parts&lt;/em&gt; list because:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;It&amp;rsquo;s a trap.&lt;/strong&gt;  The feature looks like it does one thing, but has unexpected behavior in some cases that can easily lead to bugs&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;It increases the scope of the language for little benefit.&lt;/strong&gt; The feature provides some small advantage, but requires the readers of my code to know about obscure features.  This is doubly true for &lt;em&gt;API features&lt;/em&gt; where using the feature means that other code that interacts with my code must know about the feature.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In that spirit, here are my &lt;em&gt;Bad Parts&lt;/em&gt; of ES6.&lt;/p&gt;
&lt;h4 id=&#34;const&#34;&gt;const&lt;/h4&gt;
&lt;p&gt;In older versions of JavaScript, we declared variables with the var keyword&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;.  This was mostly fine, but &lt;code&gt;var&lt;/code&gt; has peculiarities.  It creates variables that are added to the global object, or scoped to a function, but don&amp;rsquo;t respect other block boundaries.  It is also possible to reference a &lt;code&gt;var&lt;/code&gt; declared variable before it is declared. These oddities occasionally come back to bite developers.  In response ES6 introduced 2 new keywords for declaring variables: &lt;code&gt;let&lt;/code&gt; and &lt;code&gt;const&lt;/code&gt;.  These solve the primary quirks of &lt;code&gt;var&lt;/code&gt;; they are block-scoped, so a variable declared inside of a loop is not referencable outside of that loop, and trying to access the variable before it is declared in code results in a reference error. This was a big step forward.  It was also confusing, because we were given 2 solutions.&lt;/p&gt;
&lt;p&gt;A &lt;code&gt;const&lt;/code&gt; variable cannot be re-assigned after it has been declared. This is the only difference between &lt;code&gt;const&lt;/code&gt; and &lt;code&gt;let&lt;/code&gt;. This seems useful, and it can be.  The problem is the name. What it guarantees doesn&amp;rsquo;t match what most people expect from a &lt;em&gt;constant&lt;/em&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; CONSTANT &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;123&lt;/span&gt;;
&lt;span style=&#34;color:#6272a4&#34;&gt;// this will cause &amp;#34;TypeError: invalid assignment to const `CONSTANT`&amp;#34;
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;CONSTANT &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;345&lt;/span&gt;;
&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; CONSTANT_ARR &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; []
CONSTANT_ARR.push(&lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;)
&lt;span style=&#34;color:#6272a4&#34;&gt;// this will print [1] without an error
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;console.log(CONSTANT_ARR)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;const&lt;/code&gt; prevents reassignment, but it doesn&amp;rsquo;t make objects immutable.  This is a fairly weak guarantee for most value types.  Because this feature invites confusion, and &lt;code&gt;const&lt;/code&gt; is otherwise redundant with &lt;code&gt;let&lt;/code&gt;, I choose to always use &lt;code&gt;let&lt;/code&gt;.&lt;/p&gt;
&lt;h4 id=&#34;template-literal-tags&#34;&gt;Template Literal Tags&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;const&lt;/code&gt; is an example of the spec creating too many solutions to too few problems. Template literals are the inverse.  The template literal syntax was TC39&amp;rsquo;s way of tackling string interpolation and multi-line strings.  Then they decided to give it a string macro feature as well.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;ve never seen a template literal tag, they&amp;rsquo;re a little like &lt;a href=&#34;https://github.com/tc39/proposal-decorators&#34;&gt;decorators&lt;/a&gt; for strings.  Here&amp;rsquo;s an example from &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals&#34;&gt;MDN&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; person &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Mike&amp;#39;&lt;/span&gt;;
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; age &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;28&lt;/span&gt;;

&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt; myTag(strings, personExp, ageExp) {

  &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; str0 &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; strings[&lt;span style=&#34;color:#bd93f9&#34;&gt;0&lt;/span&gt;]; &lt;span style=&#34;color:#6272a4&#34;&gt;// &amp;#34;that &amp;#34;
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; str1 &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; strings[&lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;]; &lt;span style=&#34;color:#6272a4&#34;&gt;// &amp;#34; is a &amp;#34;
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;
  &lt;span style=&#34;color:#6272a4&#34;&gt;// There is technically a string after
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#6272a4&#34;&gt;// the final expression (in our example),
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#6272a4&#34;&gt;// but it is empty (&amp;#34;&amp;#34;), so disregard.
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#6272a4&#34;&gt;// var str2 = strings[2];
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;
  &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; ageStr;
  &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (ageExp &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;99&lt;/span&gt;){
    ageStr &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;centenarian&amp;#39;&lt;/span&gt;;
  } &lt;span style=&#34;color:#ff79c6&#34;&gt;else&lt;/span&gt; {
    ageStr &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;youngster&amp;#39;&lt;/span&gt;;
  }

  &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; str0 &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; personExp &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; str1 &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; ageStr;

}

&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; output &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; myTag&lt;span style=&#34;color:#f1fa8c&#34;&gt;`that &lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;${&lt;/span&gt; person &lt;span style=&#34;color:#f1fa8c&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt; is a &lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;${&lt;/span&gt; age &lt;span style=&#34;color:#f1fa8c&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;`&lt;/span&gt;;

console.log(output);
&lt;span style=&#34;color:#6272a4&#34;&gt;// that Mike is a youngster
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This isn&amp;rsquo;t totally useless. &lt;a href=&#34;https://codeburst.io/javascript-es6-tagged-template-literals-a45c26e54761&#34;&gt;Here&amp;rsquo;s a roundup of some use cases&lt;/a&gt;.  HTML sanitization is a useful trait.  And this is the currently the cleanest way to do things when you&amp;rsquo;re having to perform the same operation on all inputs to an arbitrary string template.  But that&amp;rsquo;s a relatively rare scenario, and you can also accomplish the same use cases with a (more verbose) function API rather than using tagged literals.  And for most things, the function API won&amp;rsquo;t even be worse.  This feature is not adding new capabilities, but is adding new concepts that future readers of my code have to be familiar with.  So I plan on staying clear as much as possible.&lt;/p&gt;
&lt;h4 id=&#34;overly-crazy-destructuring-expressions&#34;&gt;Overly crazy destructuring expressions&lt;/h4&gt;
&lt;p&gt;Some features are fine when used simply, but can spiral out of controls.  For instance, I am happy to write ternary statements like&lt;/p&gt;
&lt;p&gt;&lt;code&gt;let conferenceCost = isStudent ? 50 : 200&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;but they become tough to follow if you start nesting them:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;let conferenceCost = isStudent ? hasDiscountCode ? 25 : 50 : hasDiscountCode ? 100 : 200&lt;/code&gt;;&lt;/p&gt;
&lt;p&gt;This is how I feel about destructuring.  Destructuring lets you pull variables out of objects or arrays&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; {a} &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {a&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt;, b&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;3&lt;/span&gt;};
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; [b] &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; [&lt;span style=&#34;color:#bd93f9&#34;&gt;4&lt;/span&gt;, &lt;span style=&#34;color:#bd93f9&#34;&gt;5&lt;/span&gt;];
console.log(a, b) &lt;span style=&#34;color:#6272a4&#34;&gt;// 2, 4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;and also lets you rename variables, get nested values, and set defaults.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; {a&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; val1} &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {a&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt;, b&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;3&lt;/span&gt;};
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; [{b}] &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; [{a&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#bd93f9&#34;&gt;3&lt;/span&gt;, b&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#bd93f9&#34;&gt;4&lt;/span&gt;} , {c&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;5&lt;/span&gt;, d&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;6&lt;/span&gt;}];
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; {c&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#bd93f9&#34;&gt;6&lt;/span&gt;} &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {a&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt;, c&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;5&lt;/span&gt;};
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; {d&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#bd93f9&#34;&gt;6&lt;/span&gt;} &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {a&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt;, c&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;5&lt;/span&gt;};
console.log(val1, b, c) &lt;span style=&#34;color:#6272a4&#34;&gt;// 2, 4, 5, 6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;All of which is great, until you start combining those features.  For instance, this expression declares 4 variables, userName, eventType, eventDate, and eventId pulled out of different spots in the object structure of &lt;code&gt;eventRecord&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; eventRecord &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {
  user&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; { name&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;Ben M&amp;#34;&lt;/span&gt;, email&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;ben@m.com&amp;#34;&lt;/span&gt; },
  event&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;logged in&amp;#34;&lt;/span&gt;,
  metadata&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; { date&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;10-10-2017&amp;#34;&lt;/span&gt; },
  id&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;123&amp;#34;&lt;/span&gt;
};
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; {
  user&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; { name&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; userName &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;Unknown&amp;#34;&lt;/span&gt; },
  event&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; eventType &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;Unknown Event&amp;#34;&lt;/span&gt;,
  metadata&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; [date&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; eventDate],
  id&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; eventId
} &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; obj;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It&amp;rsquo;s pretty much impossible to follow.  Code like this is much easier to read with the destructuring split into parts or eliminated.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; eventRecord &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {
  user&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; { name&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;Ben M&amp;#34;&lt;/span&gt;, email&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;ben@m.com&amp;#34;&lt;/span&gt; },
  event&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;logged in&amp;#34;&lt;/span&gt;,
  metadata&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; { date&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;10-10-2017&amp;#34;&lt;/span&gt; },
  id&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;123&amp;#34;&lt;/span&gt;
};
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; userName &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; eventRecord.user.userName &lt;span style=&#34;color:#ff79c6&#34;&gt;||&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Unknown&amp;#39;&lt;/span&gt;;
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; eventDate &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; eventRecord.metadata.date;
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; {event&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;eventType&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;UnknownEvent&amp;#39;&lt;/span&gt;, id&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;eventId} &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; eventRecord;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I don&amp;rsquo;t have a clear line for when destructuring has gone too far, but anytime I can&amp;rsquo;t look at it and instantly know what variables are being declared, I know it&amp;rsquo;s time to break things down for readability.&lt;/p&gt;
&lt;h4 id=&#34;default-exports&#34;&gt;Default Exports&lt;/h4&gt;
&lt;p&gt;One nice thing about ES6 was the way it standardized things that had been accomplished using competing libraries.  Classes, Promises and modules all benefited from being folded into the spec after the community had time to absorb lessons learned from competitive user-land implementations.  ES6 modules are a great replacement for the AMD/CommonJS format wars, and provide a nice clean syntax for imports.&lt;/p&gt;
&lt;p&gt;ES6 modules provide 2 main ways of exporting values: &lt;em&gt;named exports&lt;/em&gt;, and &lt;em&gt;default exports&lt;/em&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; mainValue &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;This is the default export
&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;export default mainValue
&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;export const secondaryValue = &amp;#39;&lt;/span&gt;This is a secondary value;
&lt;span style=&#34;color:#ff79c6&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; secondaryValue2 &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &amp;#39;This is another secondary value;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A module can define multiple named exports, but only a single default export.  When importing default exports, the importing file can give the default export any name as there isn&amp;rsquo;t any lookup on name.  Named exports are imported by using the name of the variable in the exporting file, though renaming is possible.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;// default import
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; renamedMainValue from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;./the-above-example&amp;#39;&lt;/span&gt;;
&lt;span style=&#34;color:#6272a4&#34;&gt;// named import
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; {secondaryValue} from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;./the-above-example&amp;#39;&lt;/span&gt;;
&lt;span style=&#34;color:#6272a4&#34;&gt;// named import with a rename
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; {secondaryValue as otherValue} from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;./the-above-example&amp;#39;&lt;/span&gt;;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Default exports &lt;a href=&#34;https://esdiscuss.org/topic/moduleimport#content-0&#34;&gt;were the preferred syntax of the folks designing ES6&lt;/a&gt; and they intentionally gave it the cleanest syntax.  But in practice I&amp;rsquo;ve found named exports to be better.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Named exports match the names of the imported variable by default, making searching easier for those not using intelligent tooling.&lt;/li&gt;
&lt;li&gt;Named exports can be matched to variables in other values prior to an import statement being written, allowing niceties like &lt;a href=&#34;https://code.visualstudio.com/updates/v1_18#_auto-import-for-javascript-and-typescript&#34;&gt;auto-import&lt;/a&gt; for those using intelligent tooling.&lt;/li&gt;
&lt;li&gt;It&amp;rsquo;s possible to use named imports consistently for everything, but that&amp;rsquo;s only possible with default imports if you never want to export multiple values from a file.&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt; Using only named modules keep things simpler.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Naming things is good.  It promotes consistency in discussion and code.  I use named exports because I like clarity.&lt;/p&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;Thanks &lt;a href=&#34;https://babeljs.io/learn-es2015/&#34;&gt;Babel&lt;/a&gt;!&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;Or global scope, or a property on an object, or a function declaration&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;Exporting objects with multiple values as properties seems like a workaround here, but that loses the tree-shaking value that ES6 Modules provide for bundlers like webpack.&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>Weekly Links: June 3rd</title>
      <link>https://benmccormick.org/2018/06/02/weekly-links-june.html</link>
      <pubDate>Sat, 02 Jun 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/06/03/weekly-links-june.html</guid>
      <description>&lt;h3 id=&#34;javascript--the-web&#34;&gt;JavaScript &amp;amp; The Web&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://developers.google.com/web/updates/2018/05/nic67#desktop-pwas&#34;&gt;New in Chrome 67  - Desktop PWAs | Google Developers&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Google has a new process for bundling web apps as installable applications, this time based on the emerging Progressive Web App semi-standard&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.  An interesting alternative approach for smaller applications that don&amp;rsquo;t need the full electron runtime, or education apps targeting Chromebooks&lt;/p&gt;
&lt;h3 id=&#34;programming-tools&#34;&gt;Programming Tools&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/ambv/black&#34;&gt;black: The uncompromising Python code formatter | Github&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This looks like a Python version of &lt;a href=&#34;https://prettier.io/&#34;&gt;Prettier&lt;/a&gt;, and something I&amp;rsquo;d be interested in playing with.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://facebook.github.io/jest/blog/2018/05/29/jest-23-blazing-fast-delightful-testing.html&#34;&gt;Jest 23 | Jest Blog&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Jest just keeps getting better.  This release brings interactive snapshot updating, so that you can approve some changes and not others.  That&amp;rsquo;s a big UX improvement and reason enough to upgrade, but looks like there are some improved matchers and new customizability options for power users as well.  A solid release.&lt;/p&gt;
&lt;h3 id=&#34;tech--business&#34;&gt;Tech &amp;amp; Business&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://www.theverge.com/2018/6/3/17422752/microsoft-github-acquisition-rumors&#34;&gt;Microsoft has reportedly acquired Github | The Verge&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Microsoft seems to be doing everything it can to earn back love and trust from developers.  Some of that has been by investing in new stuff like Visual Studio Code, some of it has been attitude, and then things like this are just buying somebody elses love.  But I think they&amp;rsquo;ve earned back enough good will at this point that most developers will be willing to give them a chance and not assume that this will automatically be a bad thing.  Which is a big change from 5 years ago.&lt;/p&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;It&amp;rsquo;s a little vague still to really be considered a standard, but Microsoft and Google at least are providing broad support for similar sounding things that they both call PWAs, and Mozilla and Apple have been supporting the underlying technology if not the branding as much.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>Weekly Links: May 27th</title>
      <link>https://benmccormick.org/2018/05/26/weekly-links-may.html</link>
      <pubDate>Sat, 26 May 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/05/27/weekly-links-may.html</guid>
      <description>&lt;h3 id=&#34;business--technology&#34;&gt;Business &amp;amp; Technology&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://www.gatsbyjs.org/blog/2018-05-24-launching-new-gatsby-company/&#34;&gt;Gatsby contributors form Gatsby Inc. | Gatsby Blog&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This blog is built on &lt;a href=&#34;https://www.gatsbyjs.org/&#34;&gt;Gatsby&lt;/a&gt;, and I&amp;rsquo;ve &lt;a href=&#34;https://benmccormick.org/topics/gatsby&#34;&gt;written&lt;/a&gt; and &lt;a href=&#34;https://www.slideshare.net/BenMcCormick/gatsby-intro&#34;&gt;spoken&lt;/a&gt; on it a few times in the past.  So I&amp;rsquo;m really excited to see what happens with the tech as it becomes a company, while continuing to be open source.  It will be really exciting to see where they take it from here, and I think they have a real chance to be successful, especially if they can get a foothold into the ecommerce world.&lt;/p&gt;
&lt;h3 id=&#34;problem-solving&#34;&gt;Problem Solving&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;http://reinertsenassociates.com/the-cult-of-the-root-cause/&#34;&gt;The Cult of the Root Cause | Donald Reinertsen&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A really nice short post on problem solving, and how the quest to find the root cause for an issue can sometimes be a distraction.&lt;/p&gt;
&lt;h3 id=&#34;books&#34;&gt;Books&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://amzn.to/2sgXJoo&#34;&gt;Unbroken | Laura Hillenbrand&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve fallen behind on my quest to read 30 books in a year, but this month I was able to read a fantastic book that multiple friends had recommended: Unbroken.  With the &lt;a href=&#34;https://www.imdb.com/title/tt7339792/&#34;&gt;second movie&lt;/a&gt; based on the book coming out this fall, you&amp;rsquo;ll probably start to hear about this book again.  It&amp;rsquo;s been around since 2010, but I didn&amp;rsquo;t read it when it was first popular, and now I wish I had.  It is an amazing story of human perseverence, surviving trauma, and ultimately grace.  It doesn&amp;rsquo;t oversimplify the human beings whose lives it chronicles, but still manages to shine on a light on the best and worst of the human condition.  Highly recommended.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Weekly Links: May 19th</title>
      <link>https://benmccormick.org/2018/05/18/weekly-links-may.html</link>
      <pubDate>Fri, 18 May 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/05/19/weekly-links-may.html</guid>
      <description>&lt;h3 id=&#34;javascript-and-the-web&#34;&gt;JavaScript and the Web&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://changelog.com/reactpodcast&#34;&gt;The React Podcast | Michael Jackson&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I listen to a decent amount of podcasts, but I&amp;rsquo;ve usually found it tough to get into programming podcasts.  Without visually being able to see code, they&amp;rsquo;re usually either ultra high level, or get hard to follow when going into the details.  The changelog family of podcasts has generally been my favorite though, and the new&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; React podcast has been consistently excellent over it&amp;rsquo;s first 9 episodes.  Worth a listen.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.mgechev.com/2018/05/09/introducing-guess-js-data-driven-user-experiences-web/?utm_source=ponyfoo+weekly&amp;amp;utm_medium=email&amp;amp;utm_campaign=115&#34;&gt;Guess.js | Minko Gechev&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This is a crazy look at what I suspect will be the next step in static site performance stuff.  This blog does some of the cool stuff mentioned here (we prefetch links on the page thanks to Gatsby, and I use google analytics at build time to determine popular pages and populate the Most Read Articles list on the main page) but this is next level, using analytics to efficiently prefetch.  Excited to try it on the site.&lt;/p&gt;
&lt;h3 id=&#34;non-tech&#34;&gt;Non-Tech&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://amzn.to/2LdnoXK&#34;&gt;The Vision | Tom King&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Ok so I&amp;rsquo;m pretty late on this one&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;, but Tom King&amp;rsquo;s &lt;em&gt;The Vision&lt;/em&gt; is the best comic book I&amp;rsquo;ve read in years.  He&amp;rsquo;s got a &lt;a href=&#34;https://amzn.to/2IwlMq1&#34;&gt;pretty&lt;/a&gt; &lt;a href=&#34;https://amzn.to/2LcYQ0U&#34;&gt;good&lt;/a&gt; &lt;a href=&#34;https://amzn.to/2Lh3ZFd&#34;&gt;run&lt;/a&gt; going on Batman now as well, but this is a brilliant self-contained story that holds up as well as anything I&amp;rsquo;ve seen. Great art as well.&lt;/p&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;Newly relauched? I&amp;rsquo;m not totally sure of the history&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;The single edition Vision comics were originally released in 2015, though the hardcover that I purchased was just released this year.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>MobX Patterns: State Machines &amp; Flags</title>
      <link>https://benmccormick.org/2018/05/13/190000.html</link>
      <pubDate>Sun, 13 May 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/05/14/190000.html</guid>
      <description>&lt;p&gt;A few weeks ago, I was listening to the &lt;a href=&#34;https://changelog.com/reactpodcast&#34;&gt;React Podcast&lt;/a&gt;, specifically their &lt;a href=&#34;https://changelog.com/reactpodcast/5&#34;&gt;episode on State Machines&lt;/a&gt; with &lt;a href=&#34;https://twitter.com/davidkpiano&#34;&gt;David Khourshid&lt;/a&gt;.  About 20 minutes into the podcast, there was a discussion on the benefits of using enums over flags to model the state of objects that can change across multiple dimensions.  It reminded me of one of the nice patterns that &lt;a href=&#34;https://mobx.js.org/&#34;&gt;MobX&lt;/a&gt; makes possible, and I thought I&amp;rsquo;d share it here.&lt;/p&gt;
&lt;h3 id=&#34;background&#34;&gt;Background&lt;/h3&gt;
&lt;p&gt;To set the stage here, the podcast discussion centered around modeling an async process like a promise. One possible way given was to use a mix of flags and if statements like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;// loading object
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; ExampleLoader {
    constructor() {
      &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.isLoading &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;false&lt;/span&gt;;
      &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.hasError &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;false&lt;/span&gt;;
    }

    fetchData() {
      &lt;span style=&#34;color:#6272a4&#34;&gt;//fetch data from server and return it here
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    }

    &lt;span style=&#34;color:#ff79c6&#34;&gt;async&lt;/span&gt; load() {
      &lt;span style=&#34;color:#ff79c6&#34;&gt;try&lt;/span&gt; {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.isLoading &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;true&lt;/span&gt;;
        &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; data &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;await&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.fetchData();
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.isLoading &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;false&lt;/span&gt;;
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.hasError &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;false&lt;/span&gt;;
      } &lt;span style=&#34;color:#ff79c6&#34;&gt;catch&lt;/span&gt;(e) {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.hasError &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;true&lt;/span&gt;;
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.isLoading &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;false&lt;/span&gt;;
      }
    }
}

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;using one of these objects might look like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;
&lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (loader.hasError) {
  &lt;span style=&#34;color:#6272a4&#34;&gt;// show error state
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;} &lt;span style=&#34;color:#ff79c6&#34;&gt;else&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (loader.isLoading) {
  &lt;span style=&#34;color:#6272a4&#34;&gt;// show loading state
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;} &lt;span style=&#34;color:#ff79c6&#34;&gt;else&lt;/span&gt; {
  &lt;span style=&#34;color:#6272a4&#34;&gt;// show data State
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In the podcast David Khourshid criticized this as a haphazard way to manage state, that doesn&amp;rsquo;t show the whole picture.  Because we can&amp;rsquo;t easily see how the various flags combine, it&amp;rsquo;s tough to keep track of all possible states.  For instance, in the above example, did we really want to show the error state if we had an error, but have called &lt;code&gt;load()&lt;/code&gt; again and both &lt;code&gt;hasError&lt;/code&gt; and &lt;code&gt;isLoading&lt;/code&gt; are now true?  Maybe that was the intention, but maybe that was just a state that was missed during the original construction of the program.  It&amp;rsquo;s hard to tell.&lt;/p&gt;
&lt;p&gt;As an alternative to full blown state machine modeling, David advocated for an easy first step of swapping out flags for enums.  In that case the code above might look like:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; STATES &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {
  INITIAL&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;initial&amp;#39;&lt;/span&gt;,
  LOADING&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;loading&amp;#39;&lt;/span&gt;,
  ERROR&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;error&amp;#39;&lt;/span&gt;,
  LOADED&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;loaded&amp;#39;&lt;/span&gt;
}
&lt;span style=&#34;color:#6272a4&#34;&gt;// loading object
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; ExampleLoader {
    constructor() {
      &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.state &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; STATES.INITIAL;
    }

    fetchData() {
      &lt;span style=&#34;color:#6272a4&#34;&gt;//fetch data from server and return it here
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    }

    &lt;span style=&#34;color:#ff79c6&#34;&gt;async&lt;/span&gt; load() {
      &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; {LOADING, ERROR, LOADED} &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; STATES;
      &lt;span style=&#34;color:#ff79c6&#34;&gt;try&lt;/span&gt; {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.state &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; LOADING
        &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; data &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;await&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.fetchData();
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.state &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; LOADED;
      } &lt;span style=&#34;color:#ff79c6&#34;&gt;catch&lt;/span&gt;(e) {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.state &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; ERROR;
      }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;with usage like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;
&lt;span style=&#34;color:#ff79c6&#34;&gt;switch&lt;/span&gt;(loader.state) {
  &lt;span style=&#34;color:#ff79c6&#34;&gt;case&lt;/span&gt; STATES.ERROR&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;
  &lt;span style=&#34;color:#6272a4&#34;&gt;// show error state
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#ff79c6&#34;&gt;case&lt;/span&gt; STATES.LOADING&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;
  &lt;span style=&#34;color:#6272a4&#34;&gt;// show loading state
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#ff79c6&#34;&gt;case&lt;/span&gt; STATES.LOADED&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;
  &lt;span style=&#34;color:#6272a4&#34;&gt;// show data State
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#ff79c6&#34;&gt;case&lt;/span&gt; STATES.INITIAL&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;
  &lt;span style=&#34;color:#ff79c6&#34;&gt;default&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;
  &lt;span style=&#34;color:#6272a4&#34;&gt;// show blank state
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We can see just from using an enum, we&amp;rsquo;ve cleared some ambiguity: now it is clear that we should be showing a loading state when we&amp;rsquo;re loading data, even if a previous load resulted in an error.  And we&amp;rsquo;ve also been forced to remember another state distinction that was missed originally, the difference between a successful load and the initial state before load is called.  This type of Enum-based approach is really helpful for modeling complex systems and especially async process state. But it&amp;rsquo;s not perfect.  While ENUMs are great for listing out every possible state, sometimes we just need to know if an object is in a particular state.  For instance, we might have a special help-prompt component that should only show if our data is in an error state, but is otherwise divorced from the details of the data.  In that case &lt;code&gt;loader.hasError&lt;/code&gt; is simpler and  cleaner than &lt;code&gt;loader.state === STATES.ERROR&lt;/code&gt;.  It&amp;rsquo;s a straight forward named expression that doesn&amp;rsquo;t require importing a constant from another file or matching up to a string value.  Enums add some verbosity and ceremony to code that can otherwise be very simple.  Fortunately MobX allows us to have our cake and eat it too.&lt;/p&gt;
&lt;h3 id=&#34;mobx&#34;&gt;MobX&lt;/h3&gt;
&lt;p&gt;MobX is a state management solution created by &lt;a href=&#34;https://twitter.com/mweststrate&#34;&gt;Michael Weststrate&lt;/a&gt;.  It grew out of the React community but can be used with other frameworks or on it&amp;rsquo;s own.  One of its nicest features are its intelligently updated &lt;a href=&#34;https://mobx.js.org/refguide/computed-decorator.html&#34;&gt;computed properties&lt;/a&gt;.  With MobX we can write our loader object like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; {extendObservable, computed, action } from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;mobx&amp;#39;&lt;/span&gt;;
&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; STATES &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {
  INITIAL&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;initial&amp;#39;&lt;/span&gt;,
  LOADING&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;loading&amp;#39;&lt;/span&gt;,
  ERROR&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;error&amp;#39;&lt;/span&gt;,
  LOADED&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;loaded&amp;#39;&lt;/span&gt;
}
&lt;span style=&#34;color:#6272a4&#34;&gt;// loading object
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; ExampleLoader {
    constructor() {
      &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; {INITIAL, LOADING, ERROR } &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; STATES;
      extendObservable(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;, {
          state&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; INITIAL,
          isLoading&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; computed(() =&amp;gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.state &lt;span style=&#34;color:#ff79c6&#34;&gt;===&lt;/span&gt; LOADING),
          hasError&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; computed(() =&amp;gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.state &lt;span style=&#34;color:#ff79c6&#34;&gt;===&lt;/span&gt; ERROR),
          updateState&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; action(state =&amp;gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.state &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; state),
      })
    }

    fetchData() {
      &lt;span style=&#34;color:#6272a4&#34;&gt;//fetch data from server and return it here
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    }

    &lt;span style=&#34;color:#ff79c6&#34;&gt;async&lt;/span&gt; load() {
      &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; {LOADING, ERROR, LOADED} &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; STATES;
      &lt;span style=&#34;color:#ff79c6&#34;&gt;try&lt;/span&gt; {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.updateState(LOADING);
        &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; data &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;await&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.fetchData();
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.updateState(LOADED);
      } &lt;span style=&#34;color:#ff79c6&#34;&gt;catch&lt;/span&gt;(e) {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.updateState(ERROR);
      }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now we have both our state enum, and we can check specific properties.  So both of the below examples work:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;// ENUM example
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;switch&lt;/span&gt;(loader.state) {
  &lt;span style=&#34;color:#ff79c6&#34;&gt;case&lt;/span&gt; STATES.ERROR&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;
  &lt;span style=&#34;color:#6272a4&#34;&gt;// show error state
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#ff79c6&#34;&gt;case&lt;/span&gt; STATES.LOADING&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;
  &lt;span style=&#34;color:#6272a4&#34;&gt;// show loading state
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#ff79c6&#34;&gt;case&lt;/span&gt; STATES.LOADED&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;
  &lt;span style=&#34;color:#6272a4&#34;&gt;// show data State
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#ff79c6&#34;&gt;case&lt;/span&gt; STATES.INITIAL&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;
  &lt;span style=&#34;color:#ff79c6&#34;&gt;default&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;
  &lt;span style=&#34;color:#6272a4&#34;&gt;// show blank state
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;//Flags example
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (loader.hasError) {
  &lt;span style=&#34;color:#6272a4&#34;&gt;// show help component
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And because MobX takes care of the details of efficiently updating our flags based on state, we know everything will stay in sync and remain performant, without a bunch of ugly code to make sure of that.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Weekly Links: May 5th</title>
      <link>https://benmccormick.org/2018/05/04/weekly-links-may.html</link>
      <pubDate>Fri, 04 May 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/05/05/weekly-links-may.html</guid>
      <description>&lt;h3 id=&#34;intriguing-github-projects&#34;&gt;Intriguing Github Projects&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/mdx-js/mdx&#34;&gt;MDX&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Ever since I started using Gatsby to power this blog, I&amp;rsquo;ve wanted the ability to write markdown with React elements intermingled in it.  This looks like the first working version of that I&amp;rsquo;ve seen.  I&amp;rsquo;m excited to play with it.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/sharkdp/bat&#34;&gt;bat: A cat(1) clone with wings | David Peter&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This looks like a really cool project, a &amp;ldquo;cat&amp;rdquo; clone with syntax highlighting and git line indicators.  Lot&amp;rsquo;s of cool stuff being written in Rust these days.&lt;/p&gt;
&lt;h3 id=&#34;tech-and-business&#34;&gt;Tech and Business&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://www.sec.gov/Archives/edgar/data/1018724/000119312518121161/d456916dex991.htm&#34;&gt;Amazon Letter To Shareholders | Jeff Bezos&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I originally saw this letter in an article on &lt;a href=&#34;https://stratechery.com/2018/divine-discontent-disruptions-antidote/&#34;&gt;Stratechery&lt;/a&gt;, (and that piece is also great).  It&amp;rsquo;s one of the best short pieces on business that I&amp;rsquo;ve ever read.  The Stratechery piece breaks down the idea of &amp;ldquo;divinely discontent customers&amp;rdquo;, which is an amazing image.  But the other advice about how to set and maintain high standards is even better.  Just great stuff, from the leader of one of the most important companies in the world.&lt;/p&gt;
&lt;h3 id=&#34;fun&#34;&gt;Fun&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://twitter.com/jhoff/status/991408768171855873&#34;&gt;“What the customer really wanted 😏… “&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This is a new variant on one of my favorite programming jokes&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;blockquote class=&#34;twitter-tweet&#34; data-lang=&#34;en&#34;&gt;&lt;p lang=&#34;en&#34; dir=&#34;ltr&#34;&gt;What the customer really wanted 😏 &lt;a href=&#34;https://t.co/sDTbQsZb3U&#34;&gt;pic.twitter.com/sDTbQsZb3U&lt;/a&gt;&lt;/p&gt;&amp;mdash; Jayme Hoffman (@jhoff) &lt;a href=&#34;https://twitter.com/jhoff/status/991408768171855873?ref_src=twsrc%5Etfw&#34;&gt;May 1, 2018&lt;/a&gt;&lt;/blockquote&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;If anyone knows where the original version of this joke is from let me know and I&amp;rsquo;ll credit it.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>Weekly Links: April 27th</title>
      <link>https://benmccormick.org/2018/04/26/weekly-links-april.html</link>
      <pubDate>Thu, 26 Apr 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/04/27/weekly-links-april.html</guid>
      <description>&lt;h3 id=&#34;javascript--the-web&#34;&gt;JavaScript &amp;amp; The Web&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://engineering.linkedin.com/blog/2018/04/css-at-scale--linkedins-new-open-source-projects-take-on-stylesh&#34;&gt;CSS at Scale: LinkedIn’s New Open Source Projects Take on Stylesheet Performance | LinkedIn Engineering&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This is a cool new set of CSS tools from LinkedIn.  This looks most similar to CSS Modules/PostCSS to my eyes, with a focus on optimizing bundle size for both CSS and templates/components.  I&amp;rsquo;d be very interested in playing with it.&lt;/p&gt;
&lt;h3 id=&#34;programming-tools&#34;&gt;Programming Tools&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://www.joelonsoftware.com/2018/04/23/strange-and-maddening-rules/&#34;&gt;Strange and maddening rules | Joel Spoelsky&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m continuing to enjoy Joel&amp;rsquo;s series on StackOverflow.  I&amp;rsquo;ve always been more sympathetic to their moderation strategy than some, so I&amp;rsquo;ll leave it as an exercise to the reader whether the explanations presented here hold water, but definitely worth reading if you&amp;rsquo;ve ever tried contributing to StackOverflow and been frustrated.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://medium.com/@felixrieseberg/defeating-electron-e1464d075528&#34;&gt;Defeating Electron | Felix Rieseberg&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://electronjs.org/&#34;&gt;Electron&lt;/a&gt; doesn&amp;rsquo;t have the best reputation.  Any time an electron based app makes news on Hacker News, three quarters of the comments are bashing Electron and the companies that use it.  It&amp;rsquo;s been criticized recently and prominently on &lt;a href=&#34;https://daringfireball.net/2018/02/non_native_apps_threat_to_mac&#34;&gt;Daring Fireball&lt;/a&gt; and seems to generally be looked down on by &amp;ldquo;real&amp;rdquo; MacOS developers.  So I think this is a helpful response.  An Electron community member knocks down some straw-men (Electron doesn&amp;rsquo;t only exist because web developers don&amp;rsquo;t want to learn new things) and then lays out what would be needed to replace it.&lt;/p&gt;
&lt;p&gt;I think there&amp;rsquo;s an interesting tension here:  This post describes what would be needed to create a more compelling cross-platform solution from the point of view of companies and developers.  But the criticism has mostly been focused on the requirements of users, not companies.  Specifically that Electron apps tend to be slower/less-memory-efficient/less accessible/less attuned to platform specific conventions.  So companies are making the decisions that let them serve the most number of people, while evolving to meet their needs as quickly as possible, with as small cost as possible.  But they&amp;rsquo;re possibly limiting the top level quality they can achieve, and there is a possible social good being missed by the people excluded (those with lower performance machines or accessibility needs&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;).&lt;/p&gt;
&lt;h3 id=&#34;tech-and-ethics&#34;&gt;Tech and Ethics&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;http://nymag.com/selectall/2018/04/dan-mccomas-reddit-product-svp-and-imzy-founder-interview.html&#34;&gt;‘I Fundamentally Believe That My Time at Reddit Made the World a Worse Place’ | Noah Kulwin &amp;amp; Dan McComas&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A great interview on the massive potential for good or evil today&amp;rsquo;s tech products can have.  This does suggest that the problem is deeper than simply &amp;ldquo;engineers and designers behaving ethically&amp;rdquo; though.  You can get at Reddit&amp;rsquo;s issues by following the money.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://twitter.com/leinweber/status/989267343002951680?ref_src=twsrc%5Etfw&#34;&gt;A Very Good Program&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;On a lighter note, here&amp;rsquo;s the real case for engineers and designers needing to behave ethically.&lt;/p&gt;
&lt;blockquote class=&#34;twitter-tweet&#34; data-lang=&#34;en&#34;&gt;&lt;p lang=&#34;en&#34; dir=&#34;ltr&#34;&gt;I made a VGP (very good program) that makes it so it looks like I’m typing on slack whenever anyone else is typing, and stops when they stop.&lt;br&gt;&lt;br&gt;Everyone loves it so far and doesn’t find it annoying at all!&lt;a href=&#34;https://t.co/W8e2EKuVXX&#34;&gt;https://t.co/W8e2EKuVXX&lt;/a&gt; &lt;a href=&#34;https://t.co/ZZd01GxYqg&#34;&gt;pic.twitter.com/ZZd01GxYqg&lt;/a&gt;&lt;/p&gt;&amp;mdash; will leinweber (@leinweber) &lt;a href=&#34;https://twitter.com/leinweber/status/989267343002951680?ref_src=twsrc%5Etfw&#34;&gt;April 25, 2018&lt;/a&gt;&lt;/blockquote&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;I am not an accessibility expert, but I&amp;rsquo;m aware that it is a criticism of Electron.  I can&amp;rsquo;t evaluate the actual difficulty of making a native vs electron application accessible.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>The New Hello World</title>
      <link>https://benmccormick.org/2018/04/24/190000.html</link>
      <pubDate>Tue, 24 Apr 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/04/25/190000.html</guid>
      <description>&lt;p&gt;JavaScript has had a weird reputation inversion over the past decade.  For years it was the stripped down toy language that could.  It didn&amp;rsquo;t have the features people wanted, and it did have the features they didn&amp;rsquo;t want, but it ran everywhere and it was easy to just start building things.  The last decade has shown that you can actually build some serious applications in JavaScript.  But it has also eaten away at the ability to start simple and try new things.  State of the art for JavaScript apps now involves compile steps, a long tooling chain, and a million choices for developers to make.  So the folks who are helping new developers get started have a few options for teaching JavaScript:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Embrace The Complexity&lt;/strong&gt; - Want to learn to write Web Apps?  Let&amp;rsquo;s just toss you into a boilerplate that&amp;rsquo;s using node, webpack, react, redux, redux-saga, react router, glamorous, eslint, prettier, npm scripts, lodash, and babel.  This is what production apps look like, so you might as well start learning in a realistic environment.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hide The Complexity&lt;/strong&gt; - This is where we maybe use something like &lt;a href=&#34;https://codepen.io/&#34;&gt;Codepen&lt;/a&gt; to provide a sandboxed area where we may be using Babel/React/etc, but the user doesn&amp;rsquo;t have to configure or think about them too much.  My understanding is that &lt;a href=&#34;https://glitch.com/&#34;&gt;Glitch&lt;/a&gt; tries to go down this route to some extent as well.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Discard The Complexity&lt;/strong&gt; - Teach coding like it&amp;rsquo;s 2010 all over again!  This approach is to focus more on the JavaScript language as it&amp;rsquo;s implemented in the browser, using script tags without a build step, and maybe even an older/simpler library like jQuery to explain DOM concepts and CSS.  This approach can eventually evolve towards introducing more complexity.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For the past few years I&amp;rsquo;ve seen a blend of all of these approaches when I&amp;rsquo;ve looked at other folks&#39; beginner level resources.  It&amp;rsquo;s been hard to determine the best way to prepare new developers for the complexities of the development process. But good news, I think that era is finally coming to an end.&lt;/p&gt;
&lt;h3 id=&#34;the-ideal-intro&#34;&gt;The Ideal Intro&lt;/h3&gt;
&lt;p&gt;In an ideal world, we&amp;rsquo;d be able to introduce new developers to the concepts that undergird modern web apps, and teach them syntax that is as up to date as possible without having to entangle them in the implementation details and distractions of production grade tools like Babel and Webpack.  So we want them to start out writing JavaScript code that is:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Modular&lt;/li&gt;
&lt;li&gt;Cross-environment&lt;/li&gt;
&lt;li&gt;Modern (ES6+ syntax as appropriate)&lt;/li&gt;
&lt;li&gt;Simple to start with&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The last 10 years of tool build up have been primarily focused on making it easy to achieve the first 3 goals in production (along with prioritizing other needs of large scale applications).  But production tooling is by nature less concerned with #4.  Fortunately native environments are starting to catch up on the first 3, and that means we can do better.&lt;/p&gt;
&lt;h3 id=&#34;the-new-hello-world&#34;&gt;The New Hello World&lt;/h3&gt;
&lt;p&gt;Let&amp;rsquo;s say we want to frame an intro through the classic &amp;ldquo;hello world&amp;rdquo; program.  Our goals are to create a JavaScript function that can print &amp;ldquo;Hello World&amp;rdquo;, and then expand on that a bit.  And we want to teach this in a way that will still look familiar when our learners get themselves into a production JavaScript code base.&lt;/p&gt;
&lt;h4 id=&#34;bare-bones&#34;&gt;Bare Bones&lt;/h4&gt;
&lt;p&gt;We might start with something super simple like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&amp;lt;!-- index.html --&amp;gt;&lt;/span&gt;
&amp;lt;&lt;span style=&#34;color:#ff79c6&#34;&gt;html&lt;/span&gt;&amp;gt;
  &amp;lt;&lt;span style=&#34;color:#ff79c6&#34;&gt;body&lt;/span&gt;&amp;gt;
    &amp;lt;&lt;span style=&#34;color:#ff79c6&#34;&gt;h3&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;id&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;name-display&amp;#39;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style=&#34;color:#ff79c6&#34;&gt;h3&lt;/span&gt;&amp;gt;
    &amp;lt;&lt;span style=&#34;color:#ff79c6&#34;&gt;script&lt;/span&gt;&amp;gt;
      &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; displayArea &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;document&lt;/span&gt;.getElementById(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;name-display&amp;#39;&lt;/span&gt;);
      displayArea.innerHTML &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Hello World&amp;#39;&lt;/span&gt;;
    &amp;lt;/&lt;span style=&#34;color:#ff79c6&#34;&gt;script&lt;/span&gt;&amp;gt;

  &amp;lt;/&lt;span style=&#34;color:#ff79c6&#34;&gt;body&lt;/span&gt;&amp;gt;
&amp;lt;/&lt;span style=&#34;color:#ff79c6&#34;&gt;html&lt;/span&gt;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That&amp;rsquo;s about as simple as a JavaScript hello world gets.  You can access it by opening the file directly from the file system in your browser, and it&amp;rsquo;s easy enough to edit the text and see changes on refresh.&lt;/p&gt;
&lt;p&gt;But in 2018, we can do something cool next.  We want to be modular and separate concerns, so lets create a hello world module.  This is an opportunity to introduce functions and modules.  It introduces our only small tooling step: adding a simple web server.&lt;/p&gt;
&lt;h4 id=&#34;hello-modules&#34;&gt;Hello Modules&lt;/h4&gt;
&lt;p&gt;On OSX, it&amp;rsquo;s easy enough to set up a simple web server with &lt;code&gt;python -m SimpleHTTPServer 8080&lt;/code&gt;.  We can do that with our existing index.html and verify that we can now see it at &lt;code&gt;localhost:8080&lt;/code&gt; in our browsers&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;After that, we can start doing cool stuff, starting with creating a new module:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;//hello.js
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; sayHello &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; (name&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;World&amp;#39;&lt;/span&gt;) =&amp;gt; {
  &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;`Hello &lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;${&lt;/span&gt;name&lt;span style=&#34;color:#f1fa8c&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;`&lt;/span&gt;;
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is our first function.  Depending on your audience, you may want to strip this down a bit and remove the default parameter, or spend some time explaining the different concepts in play here. But the focus can be on the concept of functions, as well as the ability to export them from a module.&lt;/p&gt;
&lt;p&gt;Now we can update our index.js file to use the new function.  Assuming both files are in the same directory, that will look like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&amp;lt;!-- index.html --&amp;gt;&lt;/span&gt;
&amp;lt;&lt;span style=&#34;color:#ff79c6&#34;&gt;html&lt;/span&gt;&amp;gt;
  &amp;lt;&lt;span style=&#34;color:#ff79c6&#34;&gt;body&lt;/span&gt;&amp;gt;
    &amp;lt;&lt;span style=&#34;color:#ff79c6&#34;&gt;h3&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;id&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;name-display&amp;#39;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style=&#34;color:#ff79c6&#34;&gt;h3&lt;/span&gt;&amp;gt;
    &amp;lt;&lt;span style=&#34;color:#ff79c6&#34;&gt;script&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;type&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;module&amp;#34;&lt;/span&gt;&amp;gt;
      &lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; {sayHello} from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;./hello.js&amp;#39;&lt;/span&gt;;
      &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; displayArea &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;document&lt;/span&gt;.getElementById(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;name-display&amp;#39;&lt;/span&gt;);
      displayArea.innerHTML &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; sayHello();
    &amp;lt;/&lt;span style=&#34;color:#ff79c6&#34;&gt;script&lt;/span&gt;&amp;gt;

  &amp;lt;/&lt;span style=&#34;color:#ff79c6&#34;&gt;body&lt;/span&gt;&amp;gt;
&amp;lt;/&lt;span style=&#34;color:#ff79c6&#34;&gt;html&lt;/span&gt;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now we have a hello world built on a foundation that can scale towards modern JavaScript environments.  We have modules and modern syntax, and the only difficult setup step has been a lightweight web server so far.  The rest is just script tags.&lt;/p&gt;
&lt;h3 id=&#34;interactive&#34;&gt;Interactive&lt;/h3&gt;
&lt;p&gt;It&amp;rsquo;s easy enough now to take our module and turn it into something interactive:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&amp;lt;!-- index.html --&amp;gt;&lt;/span&gt;
&amp;lt;&lt;span style=&#34;color:#ff79c6&#34;&gt;html&lt;/span&gt;&amp;gt;
  &amp;lt;&lt;span style=&#34;color:#ff79c6&#34;&gt;body&lt;/span&gt;&amp;gt;

    &amp;lt;&lt;span style=&#34;color:#ff79c6&#34;&gt;div&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;id&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;container&amp;#39;&lt;/span&gt;&amp;gt;
      &amp;lt;&lt;span style=&#34;color:#ff79c6&#34;&gt;h2&lt;/span&gt;&amp;gt; Enter a Name and Hit The Button&amp;lt;/&lt;span style=&#34;color:#ff79c6&#34;&gt;h2&lt;/span&gt;&amp;gt;
      &amp;lt;&lt;span style=&#34;color:#ff79c6&#34;&gt;input&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;id&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;name&amp;#39;&lt;/span&gt;&amp;gt;
      &amp;lt;&lt;span style=&#34;color:#ff79c6&#34;&gt;button&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;id&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;change-name&amp;#39;&lt;/span&gt;&amp;gt;Say Hello&amp;lt;/&lt;span style=&#34;color:#ff79c6&#34;&gt;button&lt;/span&gt;&amp;gt;
      &amp;lt;&lt;span style=&#34;color:#ff79c6&#34;&gt;h3&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;id&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;name-display&amp;#39;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style=&#34;color:#ff79c6&#34;&gt;h3&lt;/span&gt;&amp;gt;
    &amp;lt;/&lt;span style=&#34;color:#ff79c6&#34;&gt;div&lt;/span&gt;&amp;gt;

    &amp;lt;&lt;span style=&#34;color:#ff79c6&#34;&gt;script&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;type&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;module&amp;#39;&lt;/span&gt;&amp;gt;
      &lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; {sayHello} from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;./hello.mjs&amp;#39;&lt;/span&gt;;

      &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; displayArea &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;document&lt;/span&gt;.getElementById(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;name-display&amp;#39;&lt;/span&gt;);
      &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; input &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;document&lt;/span&gt;.getElementById(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;name&amp;#39;&lt;/span&gt;);
      &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; button &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;document&lt;/span&gt;.getElementById(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;change-name&amp;#39;&lt;/span&gt;);

      button.addEventListener(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;click&amp;#39;&lt;/span&gt;, () =&amp;gt; {
        displayArea.innerHTML &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; sayHello(input.value);
      });
    &amp;lt;/&lt;span style=&#34;color:#ff79c6&#34;&gt;script&lt;/span&gt;&amp;gt;

  &amp;lt;/&lt;span style=&#34;color:#ff79c6&#34;&gt;body&lt;/span&gt;&amp;gt;
&amp;lt;/&lt;span style=&#34;color:#ff79c6&#34;&gt;html&lt;/span&gt;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This example introduces DOM events and let&amp;rsquo;s the user decide who to say hello to.  It also is a good jumping off point for further experimentation for a new dev.&lt;/p&gt;
&lt;h3 id=&#34;crossing-environments&#34;&gt;Crossing Environments&lt;/h3&gt;
&lt;p&gt;Going from the browser to node, even though it is simpler in some ways, is always going to be a bigger jump for newcomers because of most people&amp;rsquo;s unfamiliarity with the command line, and the base hurdle of installing node itself.  But once we&amp;rsquo;re ready to move past browsers, our new hello world can be easily translated to node land.  The biggest hurdle is in the file names.  We will have to rename or copy &lt;code&gt;hello.js&lt;/code&gt; to be named &lt;code&gt;hello.mjs&lt;/code&gt; (Node&amp;rsquo;s way of differentiating between files using ES6 syntax).  After that, we can write a simple script to start out:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;//node.mjs
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; {sayHello} from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;./hello.mjs&amp;#39;&lt;/span&gt;;
console.log(sayHello());
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And then, as long as we&amp;rsquo;re on an up to date version of Node, we can run it with &lt;code&gt;node --experimental-modules node.mjs&lt;/code&gt;.  And we will see our Hello World.&lt;/p&gt;
&lt;p&gt;There are some annoyances for beginners here.  Node only recently added module support, and beginners must&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Rename their modules to the currently non-standard mjs ending&lt;/li&gt;
&lt;li&gt;Have a recent version of Node (v8.5+)&lt;/li&gt;
&lt;li&gt;add the experimental-modules flag and learn to ignore the warning it gives&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;But overall it isn&amp;rsquo;t meaningfully harder than learning to use node has been in the past.&lt;/p&gt;
&lt;h3 id=&#34;interactive-again&#34;&gt;Interactive Again&lt;/h3&gt;
&lt;p&gt;We can make our node.js version accept a command line arg easily enough, along with more opportunities to learn about functions, arrays and conditionals.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;//node.mjs
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; {sayHello} from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;./hello.mjs&amp;#39;&lt;/span&gt;;

&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; getLast &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; list =&amp;gt; {
  &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt;(list.length) {
      &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; list[list.length &lt;span style=&#34;color:#ff79c6&#34;&gt;-&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;]
  }
  &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;null&lt;/span&gt;;
}

console.log(sayHello(getLast(process.argv)));
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;the-future&#34;&gt;The Future&lt;/h3&gt;
&lt;p&gt;I&amp;rsquo;m excited to see the new dev experience moving back closer to alignment with the production web app experience.  I think that can only be a positive things.  Some steps that will help even more if/when they happen:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Module file format standardization&lt;/strong&gt; - The .mjs extension seems to still be controversial, but it also seems a bit inevitable.  So the question will be whether it becomes more standard to use across all modular JS on the browser and node.  The current split and experimental support makes for a confusing distraction for new learners&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;De-flagging&lt;/strong&gt; - Right now Firefox and Node still require flags for using modules.  That reduces beginner friendliness.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Where is the jQuery of 2018&lt;/strong&gt; - This is more speculative, but I think the next step to a beginner friendly hello world is a &amp;ldquo;beginner friendly framework&amp;rdquo; that is based on the &amp;ldquo;one way data flow/declarative translation of state to UI&amp;rdquo; paradigm that has swept across pretty much all modern JS frameworks.  That&amp;rsquo;s an important concept to understand, and there isn&amp;rsquo;t anything I&amp;rsquo;m aware of out there right now that let&amp;rsquo;s you build with those concepts but is as approachable to newcomers as jQuery is.  jQuery was a gateway to DOM manipulation, AJAX, and functional array manipulation for a generation of developers.  React and create-react-app is probably the closest to that concept today, but it isn&amp;rsquo;t nearly as simple.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;That&amp;rsquo;s all for now.  Code samples for this are &lt;a href=&#34;https://github.com/benmccormick/hello-new&#34;&gt;on github&lt;/a&gt;.  Goodbye World.&lt;/p&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;This should work in the latest Chrome, Safari and Edge out of the box.  I encountered a bit of slowness and flakiness on Chrome, but it worked like a charm in Safari.  Firefox still has this stuff behind a flag.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>Weekly Links: April 22nd</title>
      <link>https://benmccormick.org/2018/04/21/weekly-links-april.html</link>
      <pubDate>Sat, 21 Apr 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/04/22/weekly-links-april.html</guid>
      <description>&lt;h3 id=&#34;javascript--the-web&#34;&gt;JavaScript &amp;amp; The Web&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://medium.com/@cramforce/designing-very-large-javascript-applications-6e013a3291a3&#34;&gt;Designing Very Large (JavaScript) Applications - Malte Ubl&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This is a great talk, both because of the concepts it delivers, and because it serves as sort of a funhouse mirror look at a JavaScript framework that will probably never be public.&lt;/p&gt;
&lt;h3 id=&#34;programming-tools&#34;&gt;Programming Tools&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://zeit.co/blog/hyper2&#34;&gt;Hyper 2&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A new version of the Electron-based terminal app from Zeit.  I switched back to iterm a while ago after trying Hyper for a while, I&amp;rsquo;m excited to give it another try though.&lt;/p&gt;
&lt;h3 id=&#34;tech-and-politics&#34;&gt;Tech and Politics&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://stratechery.com/2018/the-facebook-current/&#34;&gt;The Facebook Current – Ben Thompson&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Ben Thompson is the best person to read if you want to understand the broader implications of tech news, so naturally he&amp;rsquo;s all over the current Facebook situation&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Book Review: The Inmates Are Running The Asylum</title>
      <link>https://benmccormick.org/2018/04/10/190000.html</link>
      <pubDate>Tue, 10 Apr 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/04/11/190000.html</guid>
      <description>&lt;p&gt;For the past few months I&amp;rsquo;ve been working through a goal of reading 30 books in a year.  I made a list sourced from books that I&amp;rsquo;d wanted to read in a while, and books that friends recommended, and I&amp;rsquo;ve been working through it.  For the most part I&amp;rsquo;ve gotten through books pretty quickly as they&amp;rsquo;ve been generally fascinating.  Last month was the first time I hit a book that I struggled to get through a bit.  Fortunately I stuck with it, and it was worth it in the end.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://amzn.to/2qeSTYz&#34;&gt;The Inmates Are Running The Asylum&lt;/a&gt; by Alan Cooper is a book that I&amp;rsquo;d seen recommended all over the place by design-savvy developers and product folk.  Cooper is the creator of Visual Basic, a highly regarded programmer who became an even more high regarded designer, pioneering the field of interaction design (laid out in his other book &lt;a href=&#34;https://amzn.to/2IItvkP&#34;&gt;About Face&lt;/a&gt;) and the use of personas in software design.  While &lt;em&gt;About Face&lt;/em&gt; is his explanation of the techniques behind interaction design, &lt;em&gt;The Inmates Are Running The Asylum&lt;/em&gt; is his case for why interaction design is necessary as part of the software development process.  As somebody who has been working in a partial design role for the past year, it seemed like a great fit.&lt;/p&gt;
&lt;p&gt;Unfortunately, the first few chapters were a struggle.  The first 4 chapters of the book are devoted to laying out the poor &amp;ldquo;current situation&amp;rdquo; for technology when the book was written in the late 90s.  Cooper goes through a long list of poor experiences in devices and software like TVs, email clients, car remotes, alarm clocks and more.  The problem is that almost universally his examples are out of date.  People certainly still write software with bad UX, and struggle especially with software that is replacing hardware.  But they struggle in different ways now than they did 15 years ago.  Possibly due to the influence of the author, and partially due to some maturation in the field and changes in technology, the particular examples listed in these chapters fail to land. It&amp;rsquo;s possible to extrapolate some things to present day, but it makes for choppy reading.  At minimum the book would benefit greatly from a second edition.&lt;/p&gt;
&lt;p&gt;A second issue that made the book harder to apply was also related to the publish date.  This is a book that is firmly rooted in a &lt;a href=&#34;https://en.wikipedia.org/wiki/Waterfall_model&#34;&gt;waterfall&lt;/a&gt;/long release cycle view of the software development process. In fact if anything it is advocating for a more waterfall-like approach than the waterfall status quo of 2004.  I&amp;rsquo;m genuinely curious how the author would choose to communicate his critiques today in light of the normalization of agile techniques.&lt;/p&gt;
&lt;p&gt;If I haven&amp;rsquo;t scared you off yet, you&amp;rsquo;re at the same place I was 4 chapters in, wondering if I should cut my losses and give up on a great but outdated work.  Fortunately I stuck with it and reaped the benefits. The last 10 chapters are as relevant as ever in todays world.&lt;/p&gt;
&lt;p&gt;Chapter 5 describes the complementary roles of design, engineering, and business acumen in successful businesses.  Chapters 6-8 make the case for interaction designers being a distinct field that can&amp;rsquo;t easily be filled by industrial designers, visual designers, marketers or programmers. There is a particular focus on the problems of developers designing the code that they&amp;rsquo;re implementing.  Chapters 9-11 are a high level view of the principals of interaction design.  Finally chapters 12-14 describe what implementing design into a software culture looks like.  There is a ton of great content in these chapters.&lt;/p&gt;
&lt;p&gt;As a programmer who has been designing and implementing for the last year, the critiques of chapters 6-8 rang quite true.  I see all the tendencies outlined in the book dragging me away from user-focused design, and it&amp;rsquo;s a constant battle to remind myself to build for the user and not development convenience.&lt;/p&gt;
&lt;p&gt;I was familiar with many of the ideas in chapters 9 through 11 as techniques but these chapters did a really good job of laying out the heart behind them as well as making a business case for their use.  Frankly they also made me much more interested in reading &lt;a href=&#34;https://amzn.to/2IItvkP&#34;&gt;About Face&lt;/a&gt;, so hopefully I&amp;rsquo;ll be able to get a review of that up sometime soon (after I finish my current list of books).&lt;/p&gt;
&lt;p&gt;Finally, while the implementation chapters at the end struggled a bit due to being written in a pre-agile world, it holds up because it focuses a lot on creating a design culture and isn&amp;rsquo;t just stuck on prescriptive steps for integrating designers.&lt;/p&gt;
&lt;p&gt;Overall I can definitely recommend this book if you&amp;rsquo;re interested in learning more about the role of design in a healthy software development organization and you know enough about the industry to contextualize the 90s-era advice in 2018.  It is definitely a high-level book; Cooper describes it as the &amp;ldquo;business case for interaction design&amp;rdquo;, and it is written at a &amp;ldquo;business level&amp;rdquo;.  If you want a more practical and in the weeds design resource, then &lt;a href=&#34;https://amzn.to/2IItvkP&#34;&gt;About Face&lt;/a&gt; is probably a better bet.  But &lt;a href=&#34;https://amzn.to/2qeSTYz&#34;&gt;The Inmates Are Running The Asylum&lt;/a&gt; is still solid reading.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Weekly Links: April 7th</title>
      <link>https://benmccormick.org/2018/04/06/weekly-links-april.html</link>
      <pubDate>Fri, 06 Apr 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/04/07/weekly-links-april.html</guid>
      <description>&lt;h3 id=&#34;javascript-and-the-web&#34;&gt;JavaScript and the Web&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://twitter.com/dan_abramov/status/981712092611989509&#34;&gt;React Lifecycle Diagram | Dan Abramov&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Dan shared a really great illustration of the React lifecycle methods on twitter that can help you internalize how they work if you&amp;rsquo;re unfamiliar.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://martinfowler.com/articles/201803-refactoring-2nd-ed.html&#34;&gt;Announcing the Second Edition of “Refactoring”&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The upcoming second edition of &lt;a href=&#34;https://amzn.to/2IzhmhS&#34;&gt;Refactoring&lt;/a&gt; will have it&amp;rsquo;s code examples written in JavaScript.  I&amp;rsquo;d love to see more architecture-level books written for JavaScript developers.  I don&amp;rsquo;t think we have great definitive resources for those questions yet, and rewriting a classic with JS examples is a great first step.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://developers.google.com/web/updates/2018/04/present-web-pages-to-secondary-attached-displays&#34;&gt;Present web pages to secondary attached displays | Google Developers&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This is a small thing, but I thought Chrome&amp;rsquo;s experimental support for external display controls was cool, and may eventually lead to me actually using one of the many JS based presentation tools instead of Keynote.&lt;/p&gt;
&lt;h3 id=&#34;tech&#34;&gt;Tech&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://www.citylab.com/transportation/2018/03/former-uber-backup-driver-we-saw-this-coming/556427/&#34;&gt;Former Uber Backup Driver: We Saw This Coming | Citylab&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;May be some sour grapes here, but the piece raises some interesting questions about the transition from our current state to a self-driving car future, and whether a &lt;a href=&#34;https://www.caranddriver.com/features/path-to-autonomy-self-driving-car-levels-0-to-5-explained-feature&#34;&gt;Level 3&lt;/a&gt; self driving car is even a feasible goal.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.joelonsoftware.com/2018/04/06/the-stack-overflow-age/&#34;&gt;The Stack Overflow Age | Joel Spolsky&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Stack Overflow had a huge influence on my early days learning JavaScript.  I love seeing the history here from one of the founders.&lt;/p&gt;
&lt;h3 id=&#34;humor&#34;&gt;Humor&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://www.facebook.com/photo.php?fbid=10156523301334739&amp;amp;set=a.10150885243919739.471335.523144738&amp;amp;type=3&amp;amp;theater&#34;&gt;Returning To The Empress Hotel | Nick Burchill (Facebook)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;One of the funnier stories I&amp;rsquo;ve read on the internet in a while.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Weekly Links: March 30th</title>
      <link>https://benmccormick.org/2018/03/29/weekly-links-march.html</link>
      <pubDate>Thu, 29 Mar 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/03/30/weekly-links-march.html</guid>
      <description>&lt;p&gt;A big pile of links for Easter weekend.  Happy Easter everybody!&lt;/p&gt;
&lt;h3 id=&#34;javascript-and-the-web&#34;&gt;JavaScript and the Web&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://hacks.mozilla.org/2018/03/es-modules-a-cartoon-deep-dive/&#34;&gt;ES modules: A cartoon deep-dive | Lin Clark&lt;/a&gt; - As usual, Lin Clark offers a great approachable explanation of a complex topic.  Here she gets into the weeds of how ES modules are implemented in browsers, and how the module syntax differs from CommonJS.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://blog.isquaredsoftware.com/2018/03/redux-not-dead-yet/&#34;&gt;Redux - Not Dead Yet! | Mark Erickson&lt;/a&gt; - A good explainer of where Redux fits into the React landscape today.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html&#34;&gt;Update on Async Rendering | Brian Vaughn&lt;/a&gt; - Important read for React devs.  There are changes coming to the core lifecycle methods.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://furbo.org/2018/03/28/system-fonts-in-css/&#34;&gt;System Fonts in CSS | Craig Hockenberry&lt;/a&gt; - I&amp;rsquo;m always happy to see improvements to the default font situation on the web&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.   I don&amp;rsquo;t love relying on custom loaded fonts for this blog and I wish there were more high quality fonts that were reliably available without resorting to loading your own.  This particular feature doesn&amp;rsquo;t pass the &amp;ldquo;caniuse test&amp;rdquo; for now though; Chrome and Safari support it, but there&amp;rsquo;s nothing from Edge or Firefox yet.&lt;/p&gt;
&lt;h3 id=&#34;command-line-tips&#34;&gt;Command Line Tips&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://zwischenzugs.com/2018/03/26/git-log-the-good-parts/&#34;&gt;git log – the Good Parts | Ian Miell&lt;/a&gt; - A good rundown of some of the things you can do with git log.  It misses that you can use &lt;code&gt;--author&lt;/code&gt; to filter by the committer though, which is a flag I use all the time when I know who did a specific piece of work but am vague on what actually changed.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://rachelbythebay.com/w/2018/03/26/w/&#34;&gt;Why I usually run ‘w’ first when troubleshooting unknown machines&lt;/a&gt; - Here&amp;rsquo;s a useful command line command I didn&amp;rsquo;t know about.  &lt;code&gt;w&lt;/code&gt; shows you a list of users currently on a machine and what they&amp;rsquo;re doing.&lt;/p&gt;
&lt;h3 id=&#34;code-style-documentation-and-code-reviews&#34;&gt;Code Style, Documentation and Code Reviews&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;http://bradfrost.com/blog/post/just/&#34;&gt;“Just” | Brad Frost&lt;/a&gt; - A good reminder to not assume everybody has our accumulated knowledge.  I&amp;rsquo;ve found a good cure for this is to spend some time working with programming tools I have no experience in.  Trying to install gems in Ruby for instance always reminds me how confusing npm was when I started using it.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://blog.timoxley.com/post/47041269194/avoid-else-return-early&#34;&gt;Avoid Else, Return Early | Tim Oxley&lt;/a&gt; - I&amp;rsquo;ve found this pattern of short-circuiting functions to produce very readable code.  I&amp;rsquo;ve also seen these referred to as &lt;em&gt;guard statements&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.janestreet.com/putting-the-i-back-in-ide-towards-a-github-explorer/&#34;&gt;Putting the I back in IDE: Towards a Github Explorer| Jane Street Tech Blog &lt;/a&gt; - This is an interesting idea, although I was a bit weirded out by the idea of commenting in the source files to leave code review comments.  The idea of deeper editor integration is excellent though, and I&amp;rsquo;d love to see Github evolve further in this direction with their Atom plugin.&lt;/p&gt;
&lt;h3 id=&#34;privacy-in-the-news&#34;&gt;Privacy in the news&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://arstechnica.com/information-technology/2018/03/facebook-scraped-call-text-message-data-for-years-from-android-phones/&#34;&gt;Facebook scraped call, text message data for years from Android phones | Ars Technica&lt;/a&gt; - It&amp;rsquo;s been a bad few weeks for Facebook.  You can maybe get away with trying to get everyone&amp;rsquo;s data, and you can maybe get away with being careless with user data, but when you&amp;rsquo;re as big as Facebook is, you absolutely can&amp;rsquo;t do both.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.theverge.com/2018/3/28/17172548/gdpr-compliance-requirements-privacy-notice&#34;&gt;How Europe’s new privacy rule is reshaping the internet | The Verge&lt;/a&gt; - GDPR is a big deal.  If you&amp;rsquo;re involved in web products that store user information, you should understand this.  I&amp;rsquo;m excited to see meaningful regulation on privacy issues that seems to be reasonably well written.&lt;/p&gt;
&lt;h3 id=&#34;humor&#34;&gt;Humor&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://www.johndcook.com/blog/2018/03/28/cow-astrology/&#34;&gt;Cow Astrology | John Cook&lt;/a&gt; - When a mathematician examines the implications of astrology&amp;rsquo;s claims.&lt;/p&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;Or I would always be happy if there was ever anything to be happy about.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>Front End Computer Science Basics: Boolean Logic</title>
      <link>https://benmccormick.org/2018/03/26/190000.html</link>
      <pubDate>Mon, 26 Mar 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/03/27/190000.html</guid>
      <description>&lt;p&gt;&lt;em&gt;This is the second post in a series of posts on Computer Science basics for front end developers.  The goal is to focus on the practical implications of basic CS theory for JavaScript development.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Modern programmers owe a lot to the efforts of many head in the sky theoretical mathematicians from the 1800s and early 1900s who were searching for mathematical truths and ended up making discoveries that serve as the basis of many modern computing inventions.  Boolean Algebra is one of a few branches of mathematics that was developed for purely theoretical reasons that has ended up shaping the computer revolution.  It fortunately has the virtue of being a relatively approachable to mathematical newbies.&lt;/p&gt;
&lt;p&gt;Boolean algebra is a study of operations on logical values. Or in more understandable language, it is studying the rules of logic when we&amp;rsquo;re limited to dealing with only 2 types of values, true or false.  The basic building blocks of boolean algebra are incredibly simple: in addition to the true and false values, usually encoded as 0 for false and 1 for true, boolean algebra considers 3 basic operations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The &amp;ldquo;AND&amp;rdquo; operator (&lt;code&gt;∧&lt;/code&gt;)&lt;/strong&gt; - &lt;code&gt;a∧b&lt;/code&gt; is true if and only if &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt; are both true.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The &amp;ldquo;OR&amp;rdquo; operator (&lt;code&gt;∨&lt;/code&gt;)&lt;/strong&gt; - &lt;code&gt;a∨b&lt;/code&gt; is true if at least one of &lt;code&gt;a&lt;/code&gt; or &lt;code&gt;b&lt;/code&gt; are true and false otherwise.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The &amp;ldquo;NOT&amp;rdquo; operator (&lt;code&gt;¬&lt;/code&gt;)&lt;/strong&gt; - &lt;code&gt;¬&lt;/code&gt; is a unary operator. It only affects a single value.  &lt;code&gt;¬a&lt;/code&gt; is true if &lt;code&gt;a&lt;/code&gt; is false, and false if &lt;code&gt;a&lt;/code&gt; is true.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Of course this is a whole field of mathematics, so the interesting part comes as you start combining these pieces.  Mathematicians have discovered many &amp;ldquo;laws&amp;rdquo; that apply to boolean logic.  Some of these will probably look familiar to those of you who took high school algebra.  Here&amp;rsquo;s a sample of the laws from &lt;a href=&#34;https://en.wikipedia.org/wiki/Boolean_algebra&#34;&gt;Wikipedia&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;boolean-laws.png&#34; alt=&#34;Boolean logic laws&#34;&gt;&lt;/p&gt;
&lt;p&gt;The last 3 especially are worth remembering.  Taking them out of mathematical notation for a second and using pseudocode instead, the rules are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Double Negation: &lt;code&gt;not not x == x&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;De Morgan 1 &lt;code&gt;(not x) and (not y) === not (x or y)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;De Morgan 2 &lt;code&gt;(not x) or (not y) === not (x and y)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;boolean-algebra-in-javascript&#34;&gt;Boolean Algebra in JavaScript&lt;/h3&gt;
&lt;p&gt;For most JavaScript developers, the preceding description of boolean algebra probably seemed suspiciously familiar.  It turns out that JavaScript has all the base units of boolean algebra in its core language.  True and false are represented by the appropriately named boolean primitives &lt;code&gt;true&lt;/code&gt; and &lt;code&gt;false&lt;/code&gt;.  AND, OR, and NOT are represented by &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt;, &lt;code&gt;||&lt;/code&gt; and &lt;code&gt;!&lt;/code&gt; respectively.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;boolean-mappings.png&#34; alt=&#34;mapping of operators between pseudocode, mathematical and JavaScript notation&#34;&gt;&lt;/p&gt;
&lt;p&gt;So a JavaScript statement like&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; x &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;false&lt;/span&gt;;
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; y &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;true&lt;/span&gt;
&lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt;(x &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; y) {  &lt;span style=&#34;color:#6272a4&#34;&gt;// false
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;  willNeverHappen();
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;is equivalent to &lt;code&gt;x∧y&lt;/code&gt; in boolean algebra notation.  But this being JavaScript, there are some quirks and things to know about.&lt;/p&gt;
&lt;p&gt;First of all it&amp;rsquo;s worth noting that boolean logic in JavaScript is lazy by default.  That means that JavaScript will only evaluate enough of a boolean expression to know what the result will be.  So in an expression like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; alwaysReturnTrue &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; () =&amp;gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;true&lt;/span&gt;;
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; alwaysReturnFalse &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; () =&amp;gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;false&lt;/span&gt;;
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; value &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; alwaysReturnFalse() &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; alwaysReturnTrue();
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;the function &lt;code&gt;alwaysReturnTrue&lt;/code&gt; will never be called.  This will matter when we start talking about real world takeaways.&lt;/p&gt;
&lt;p&gt;The second JavaScript quirk gets its own section.  Because booleans get more complicated when they interact with the rest of the JavaScript world.&lt;/p&gt;
&lt;h3 id=&#34;truthy-and-falsy&#34;&gt;Truthy and Falsy&lt;/h3&gt;
&lt;p&gt;When JavaScript conditionals like the if statement evaluate an expression, they aren&amp;rsquo;t strictly evaluating to see if something is the boolean values &lt;code&gt;true&lt;/code&gt; or &lt;code&gt;false&lt;/code&gt;.   Instead they&amp;rsquo;re looking to see if the expression is &lt;em&gt;truthy&lt;/em&gt; or &lt;em&gt;falsy&lt;/em&gt;.  This isn&amp;rsquo;t the kindergarten version of booleans, instead it&amp;rsquo;s JavaScript&amp;rsquo;s way of handling the fact that not all expressions are boolean.  Rather than requiring you to cast your values to boolean or use a statement that produces a boolean, JavaScript instead treats every value as either truthy or falsy.  The rules for this are reasonably consistent and easy to follow once you understand what is happening&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.  It turns out that most values are truthy, so it is easiest to just learn the falsy values.  In JavaScript the falsy values are:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;false&lt;/span&gt;,
&lt;span style=&#34;color:#ff79c6&#34;&gt;null&lt;/span&gt;,
&lt;span style=&#34;color:#ff79c6&#34;&gt;undefined&lt;/span&gt;,
&lt;span style=&#34;color:#bd93f9&#34;&gt;0&lt;/span&gt;,
&lt;span style=&#34;color:#ff79c6&#34;&gt;NaN&lt;/span&gt;,
&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#6272a4&#34;&gt;// or &amp;#34;&amp;#34;
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;document&lt;/span&gt;.all &lt;span style=&#34;color:#6272a4&#34;&gt;// Special case browser hack just for fun
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If an expression that evaluates to one of these values is read into a boolean context like an if statement or ternary, it will be treated as false.  Any other value will be read as true.&lt;/p&gt;
&lt;h3 id=&#34;implications-and-hacks&#34;&gt;Implications and Hacks&lt;/h3&gt;
&lt;p&gt;So far we&amp;rsquo;ve gone through some theory, as well as JavaScript&amp;rsquo;s own quirks.  But now let&amp;rsquo;s talk about 3 different implications of this stuff for day to day JavaScript programming.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Shortcuts using the  &amp;amp;&amp;amp; and || operators&lt;/strong&gt; - It&amp;rsquo;s fairly common, especially in special context like minified code and JSX expressions in React, to run into code that get&amp;rsquo;s clever with the lazy behavior of JavaScript boolean operators.  Specifically the &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; statement often get&amp;rsquo;s used as an inline if statement like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; userID &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; showID &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; getUserID();
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;which is equivalent to&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; userID;
&lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (showID) {
  userID &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; getUserID();
} &lt;span style=&#34;color:#ff79c6&#34;&gt;else&lt;/span&gt; {
  userID &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; showID; &lt;span style=&#34;color:#6272a4&#34;&gt;//presumably false or null
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The &lt;code&gt;||&lt;/code&gt; statement can be used for a similar purpose, usually to provide a fallback value.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; createNewUser(providedRole) {
  &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt;  userRole &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; providedRole &lt;span style=&#34;color:#ff79c6&#34;&gt;||&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;basic-user&amp;#39;&lt;/span&gt;;
  &lt;span style=&#34;color:#6272a4&#34;&gt;//...
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It&amp;rsquo;s important to be careful with this type of use though, because if it would be valid for the user input to be a falsy value like &lt;code&gt;&#39;&#39;&lt;/code&gt;, &lt;code&gt;null&lt;/code&gt; or &lt;code&gt;0&lt;/code&gt;, this can introduce subtle bugs.  More on that in a second.&lt;/p&gt;
&lt;p&gt;I wouldn&amp;rsquo;t personally relying too heavily on this technique.  Besides the possibility of subtle bugs, it isn&amp;rsquo;t very approachable for new developers, especially if you try nesting logic this way.  But you should know how it works since you will see it, especially in minified code you may need to debug and JSX.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;!! for casting&lt;/strong&gt; - Another common idiom to be aware of is the use of double negation to cast values to a boolean.  It is fairly common when you have code that is expecting a boolean and not just a truthy/falsy value to convert the value to a boolean.  One way to do that is using the &lt;code&gt;Boolean&lt;/code&gt; constructor, like &lt;code&gt;var bool = Boolean(value)&lt;/code&gt;, but another method is to use double negation.  The first negation evaluates to the boolean that is opposite the truthy/falsy value, and the second one flips it back to the original truthy/falsy state, but as a boolean.&lt;/p&gt;
&lt;p&gt;I personally find this notation to be less confusing than the &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt;/&lt;code&gt;||&lt;/code&gt; shortcuts, but your mileage may vary.  Either way, it&amp;rsquo;s important to understand its role since it is common to find &lt;code&gt;!!&lt;/code&gt;s in real world code.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;0s and empty strings are dangerous&lt;/strong&gt; - For our last quirk, let&amp;rsquo;s imagine a code example function &lt;code&gt;getCountFromServer&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; getUserCountFromServer &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;async&lt;/span&gt; () =&amp;gt; {
    &lt;span style=&#34;color:#ff79c6&#34;&gt;try&lt;/span&gt; {
      &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; response &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;await&lt;/span&gt; fetch(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;users&amp;#39;&lt;/span&gt;);
      &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; users &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; response.json()
      &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; users.length;
    } &lt;span style=&#34;color:#ff79c6&#34;&gt;catch&lt;/span&gt; (e) {
      &lt;span style=&#34;color:#6272a4&#34;&gt;// if we can&amp;#39;t get the count, return null
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;      &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;null&lt;/span&gt;;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This function makes a request from the server, and then returns the number of users, or &lt;code&gt;null&lt;/code&gt; if it can&amp;rsquo;t get the value from the server for whatever reason.  Maybe not the best error handling, but certainly something you could see in real world code.  If we want to test to see if this function got data correctly, we have to be careful.  We might want to simplify our testing by taking advantage of &lt;code&gt;null&lt;/code&gt;&amp;rsquo;s falsiness like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; userCount &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;await&lt;/span&gt; getUserCountFromServer();
&lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (userCount) {
  &lt;span style=&#34;color:#6272a4&#34;&gt;// do something with the info
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;} &lt;span style=&#34;color:#ff79c6&#34;&gt;else&lt;/span&gt; {
  &lt;span style=&#34;color:#6272a4&#34;&gt;//handle the case where the number failed to load
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Do you see the bug?  It&amp;rsquo;s subtle.  With code written like this, if there are no users it will be treated the same as if the number had failed to load at all.  This is a pretty common bug in situations where a value might be undefined or null, but could also be a number.  Strings have a similar issue.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s important to understand that if 0 or empty strings are a valid value for a variable, you can&amp;rsquo;t rely on a general falsiness check to see if the value is defined.  Instead it&amp;rsquo;s better to either define the exact falsy value you expect for &amp;ldquo;no value&amp;rdquo; (null in this case) or to check based on type.  For instance in this case, you could rewrite the code to look for a number:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; userCount &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;await&lt;/span&gt; getUserCountFromServer();
&lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#ff79c6&#34;&gt;typeof&lt;/span&gt; userCount &lt;span style=&#34;color:#ff79c6&#34;&gt;===&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;number&amp;#39;&lt;/span&gt;) {
  &lt;span style=&#34;color:#6272a4&#34;&gt;// do something with the info
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;} &lt;span style=&#34;color:#ff79c6&#34;&gt;else&lt;/span&gt; {
  &lt;span style=&#34;color:#6272a4&#34;&gt;//handle the case where the number failed to load
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;feedback-welcome&#34;&gt;Feedback Welcome&lt;/h3&gt;
&lt;p&gt;This is the second post in a new series, and I&amp;rsquo;d love to hear whether it is helpful for you, and any other topics you&amp;rsquo;d like to see covered. Feel free to reach out on &lt;a href=&#34;https://twitter.com/_benmccormick&#34;&gt;Twitter&lt;/a&gt; or &lt;a href=&#34;mailto:ben@benmccormick.org&#34;&gt;email&lt;/a&gt;.  And if you see anything that looks wrong or misleading to you, don&amp;rsquo;t hesitate to &lt;a href=&#34;https://github.com/benmccormick/benmccormickorg/issues/new&#34;&gt;open an issue&lt;/a&gt; on my blog&amp;rsquo;s github repo.&lt;/p&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;The exception for me are empty arrays.  They get evaluated as truthy in JavaScript and falsy in Python, and I can never remember which is which without testing.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>Weekly Links: March 24th</title>
      <link>https://benmccormick.org/2018/03/23/weekly-links-march.html</link>
      <pubDate>Fri, 23 Mar 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/03/24/weekly-links-march.html</guid>
      <description>&lt;h3 id=&#34;tc39-and-the-future-of-javascriptecmascript&#34;&gt;TC39 and the future of JavaScript/ECMAScript&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://developers.google.com/web/updates/2018/03/smooshgate&#34;&gt;#SmooshGate FAQ  |  Mathias Bynens&lt;/a&gt; - A great explanation both of the background behind the recent twitter controversy over &lt;code&gt;Array.prototype.smoosh&lt;/code&gt; as well as the TC39 process generally.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/zenparsing/js-classes-1.1&#34;&gt;js-classes-1.1 | Allen Wirfs-Brock&lt;/a&gt; - This is the new proposal for expanding JS classes I mentioned in my &lt;a href=&#34;https://benmccormick.org/2018/03/16/proposals-in-production/&#34;&gt;post&lt;/a&gt; last Friday.  It aims to be a more minimalist take on expanding class capabilities (primarily adding private state syntax) than other proposals that have come along over the last few years.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://gist.github.com/wycats/b1c96c67074396a239abd60f55087adc&#34;&gt;thoughts.md | Yehuda Katz&lt;/a&gt; - This was a response to the JS Classes 1.1 proposal from Yehuda Katz, the lead proponent of adding decorator syntax for JavaScript classes.  He compares the new proposal to existing proposals, with specific concerns for how it would interop with decorators.&lt;/p&gt;
&lt;h3 id=&#34;computer-science-and-software-engineering&#34;&gt;Computer Science and Software Engineering&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://medium.com/basecs&#34;&gt;basecs | Vaidehi Joshi&lt;/a&gt; - While I&amp;rsquo;ve been starting to consider how to explain CS concepts for front end developers without a CS background, I found this excellent beginner set of CS articles written by Vaidehi Joshi on Medium over the past year.  Worth diving into, especially if you like fun visuals.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.nrwl.io/the-3-skills-that-helped-me-become-a-better-software-engineer-8b06a37becf3&#34;&gt;The 3 Skills That Helped Me Become a Better Software Engineer | Victor Savkin&lt;/a&gt; - This is worth sharing solely for the advice about mental models.  In my experience the ability to think in abstractions (and understand when you need to dig deeper) is one of the biggest hurdles in programming when trying to grow from a beginner to a more advanced software engineer.&lt;/p&gt;
&lt;h3 id=&#34;books&#34;&gt;Books&lt;/h3&gt;
&lt;p&gt;I&amp;rsquo;ve been working through a goal to read 30 books in a year, and have worked through a few more books recently.  Here are two good ones.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://amzn.to/2Gbh9R2&#34;&gt;The Martian | Andy Weir&lt;/a&gt; - Yes I know I&amp;rsquo;m 3 years late on this one.  But I&amp;rsquo;m sure there are other lost souls like me who entered 2018 without reading this book.  If you love tech and science (and I&amp;rsquo;m guessing you do if you&amp;rsquo;re reading this), you should find a way to read The Martian.  My first thought when I started reading it was &amp;ldquo;This is great&amp;rdquo;.  My second thought was &amp;ldquo;How in the world did this end up becoming a Hollywood Blockbuster starring Matt Damon?&amp;rdquo;.  The Martian is unapologetically geeky, and it is &amp;ldquo;real science&amp;rdquo; fiction, with a very human core. I loved it.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://amzn.to/2G1h9ah&#34;&gt;Death By Meeting | Patrick Lencioni&lt;/a&gt; - This was a recommendation from my manager, and is a great read for anyone who wants to improve the meetings they&amp;rsquo;re in at work.  It&amp;rsquo;s written in a &amp;ldquo;business fable&amp;rdquo; style, with a story serving to illustrate the principles it is trying to teach.  One thing I love is that it tells the story of the principles being implemented from a lower rung employee, rather than a top-down executive driven approach, so hopefully it can be inspirational to you even if you feel like you wouldn&amp;rsquo;t be able to change your meeting culture even if you knew what to do.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Front End Computer Science Basics: Variables and Memory</title>
      <link>https://benmccormick.org/2018/03/20/190000.html</link>
      <pubDate>Tue, 20 Mar 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/03/21/190000.html</guid>
      <description>&lt;p&gt;A few weeks ago, I asked for input on the idea of &lt;a href=&#34;https://benmccormick.org/2018/02/20/cs-for-fe/&#34;&gt;resources on Computer Science for front end developers&lt;/a&gt;.  Because there was a decent amount of interest, I&amp;rsquo;m planning on fleshing out the idea a bit with a small series of posts on CS basics.  These posts will cover some concepts that would usually be covered in an intro level CS course.  If folks find them helpful I may move on to more advanced topics like Data Structures &amp;amp; Algorithms, the software abstractions that modern web development is built on top of, and other math/theory topics.&lt;/p&gt;
&lt;p&gt;With these posts I&amp;rsquo;m not trying to replicate a CS intro course and won&amp;rsquo;t cover everything.  I&amp;rsquo;m not trying to teach anyone how to program.  Instead I&amp;rsquo;m covering the ideas and details behind concepts that FE devs may have learned by doing but never been exposed to from an theory point of view.  I am not an academic, so the goal will be to keep a casual tone focused on the practical implications of theory to a Front End developer.  If I&amp;rsquo;m successful, these posts will give you a better set of mental models when working to understand the code you&amp;rsquo;re reading and writing every day.  That&amp;rsquo;s plenty of throat-clearing, so now I&amp;rsquo;m going to jump into one of the most fundamental building blocks of any programming language: variables.&lt;/p&gt;
&lt;h3 id=&#34;what-are-variables-not-as-obvious-as-it-sounds&#34;&gt;What are Variables? (Not as obvious as it sounds)&lt;/h3&gt;
&lt;p&gt;Variables in programming languages are symbols that we assign to represent a value.  That seems simple enough, but that sentence is too vague to properly account for the complexity of reality.  When dealing with variables in the real world, it&amp;rsquo;s important to have a good mental model of how they really behave, or you may become confused by how your programs act.  For instance if you believe that variables are always live references to whatever other variable they were assigned to, you may be surprised by the behavior of this snippet:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; a &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;;
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; b &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; a;
a &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt;;
console.log(b) &lt;span style=&#34;color:#6272a4&#34;&gt;// prints 1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;and if you believe that variables always point to a unique value that is created when you assign to them, you might be surprised by this one:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; a &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; [&lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;, &lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt;, &lt;span style=&#34;color:#bd93f9&#34;&gt;3&lt;/span&gt;]
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; b &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; a;
a.push(&lt;span style=&#34;color:#bd93f9&#34;&gt;4&lt;/span&gt;)
console.log(b) &lt;span style=&#34;color:#6272a4&#34;&gt;// prints [1, 2, 3, 4]
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Knowing generally that a variable points to a value is a great start.  But a proper understanding of the model that a programming language uses for variables can help you avoid subtle bugs.&lt;/p&gt;
&lt;h3 id=&#34;how-variables-work&#34;&gt;How Variables Work&lt;/h3&gt;
&lt;p&gt;Here&amp;rsquo;s the most important sentence for gaining a proper understanding of how variables work: &amp;ldquo;A variable points to a location in memory.&amp;rdquo;  Explaining how memory is organized and allocated is outside the scope of this post, but for now it&amp;rsquo;s sufficient to just understand memory as a long list of blocks, each of which has it&amp;rsquo;s own address.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;./memory1.png&#34; alt=&#34;memory as a series of boxes&#34;&gt;&lt;/p&gt;
&lt;p&gt;When a variable is assigned to, it points to the address of whatever value is on the right hand side of the assignment expression (if newly created, the value is assigned an open address in memory first).&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;./memory2.png&#34; alt=&#34;assignment of a variable&#34;&gt;&lt;/p&gt;
&lt;p&gt;If another variable is assigned to the first variable, it too will point to that same address in memory&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;./memory3.png&#34; alt=&#34;assignment of a variable to the value of another variable&#34;&gt;&lt;/p&gt;
&lt;p&gt;Finally if we reassign the original variable, it will point to a new location in memory, and the second variable will continue to point to the same location.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;./memory4.png&#34; alt=&#34;reassigning the original variable&#34;&gt;&lt;/p&gt;
&lt;p&gt;Function arguments are based on these same concepts.  When a function is called, the argument variables are assigned to point at the memory address of the value passed into the function.&lt;/p&gt;
&lt;h3 id=&#34;mutable-vs-immutable-variables&#34;&gt;Mutable vs Immutable Variables&lt;/h3&gt;
&lt;p&gt;This memory address stuff can seem pretty abstract, and not very useful, but it&amp;rsquo;s a great gateway to understanding more practical topics.  A while back I wrote a post about &lt;a href=&#34;https://benmccormick.org/2016/06/04/what-are-mutable-and-immutable-data-structures-2/&#34;&gt;mutable and immutable data&lt;/a&gt;.  If you&amp;rsquo;re unfamiliar with the concepts you can read the original article for background.  But basically, JavaScript values are divided into 2 categories: primitives like booleans, strings, and numbers which are immutable, and objects which are mutable.  Immutable primitives can&amp;rsquo;t be changed, when they&amp;rsquo;re operated on they can only be replaced with a new value.  Mutable objects can be changed in place.  That &amp;ldquo;in place&amp;rdquo; qualifier can seem a bit hazy without understanding the underlying memory situation, but now we can explain this more clearly: the value for a primitive will never change within a memory location, a variable will instead have to point to a new location in memory.  A mutable variable can be modified without changing it&amp;rsquo;s location in memory.  This is the explanation behind our confusing example from earlier.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; a &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; [&lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;, &lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt;, &lt;span style=&#34;color:#bd93f9&#34;&gt;3&lt;/span&gt;]
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; b &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; a;
a.push(&lt;span style=&#34;color:#bd93f9&#34;&gt;4&lt;/span&gt;)
console.log(b) &lt;span style=&#34;color:#6272a4&#34;&gt;// prints [1, 2, 3, 4]
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Because &lt;code&gt;b&lt;/code&gt; points to the same location in memory as &lt;code&gt;a&lt;/code&gt;, when we mutate &lt;code&gt;a&lt;/code&gt;, &lt;code&gt;b&lt;/code&gt; continues to point to the same array as &lt;code&gt;a&lt;/code&gt; and sees the same changes we performed on &lt;code&gt;a&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&#34;implications-and-gotchas&#34;&gt;Implications and Gotchas&lt;/h3&gt;
&lt;p&gt;There are a few practical implications of these concepts, and gotchas that folks with the wrong mental model around variables tend to run into.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;===&lt;/code&gt; is based on location in memory for objects&lt;/strong&gt; - While it does compare primitive values directly to see if they&amp;rsquo;re the same value, for objects, &lt;code&gt;===&lt;/code&gt; compares by reference.  So the following code works in a way that people might not expect if they don&amp;rsquo;t understand variables.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; a &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {x&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt;};
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; b &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; a;
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; c &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {x&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt;};
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; sameReference &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; x =&amp;gt; x;
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; d &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; sameReference(a)

console.log(a &lt;span style=&#34;color:#ff79c6&#34;&gt;===&lt;/span&gt; b) &lt;span style=&#34;color:#6272a4&#34;&gt;// true
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;console.log(a &lt;span style=&#34;color:#ff79c6&#34;&gt;===&lt;/span&gt; c) &lt;span style=&#34;color:#6272a4&#34;&gt;// false
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;console.log(a &lt;span style=&#34;color:#ff79c6&#34;&gt;===&lt;/span&gt; d) &lt;span style=&#34;color:#6272a4&#34;&gt;// true
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;&lt;strong&gt;Modifying objects in functions modifies them outside of the function scope&lt;/strong&gt; - This is a pretty common gotcha for folks who don&amp;rsquo;t understand variables and memory.  When they have a bad mental model of function arguments, you get code like the following made up example.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;// function to create a contact that is ready to send
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; formatContactForSend &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; contact =&amp;gt; {
  contact.fullName &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; contact.firstName &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; contact.lastName;
  &lt;span style=&#34;color:#ff79c6&#34;&gt;delete&lt;/span&gt; contact.id;
  &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; contact;
}
&lt;span style=&#34;color:#6272a4&#34;&gt;// get a contact from somewhere
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; newContact &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {
  id&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;,
  firstName&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Ben&amp;#39;&lt;/span&gt;,
  lastName&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;McCormick&amp;#39;&lt;/span&gt;
};
&lt;span style=&#34;color:#6272a4&#34;&gt;// send along the formatted version of the contact
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;send(formatContactForSend(newContact));

&lt;span style=&#34;color:#6272a4&#34;&gt;//oops
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;console.log(newContact); &lt;span style=&#34;color:#6272a4&#34;&gt;/* {
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;  firstName: &amp;#34;Ben&amp;#34;,
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;  lastName: &amp;#34;McCormick&amp;#34;,
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;  fullName: &amp;#34;Ben McCormick&amp;#34;
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;}
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;*/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start=&#34;3&#34;&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;const&lt;/code&gt; isn&amp;rsquo;t really a constant&lt;/strong&gt; - &lt;a href=&#34;https://benmccormick.org/2015/09/14/es5-es6-es2016-es-next-whats-going-on-with-javascript-versioning/&#34;&gt;ES6&lt;/a&gt; introduced the new keywords for declaring variables &lt;code&gt;let&lt;/code&gt; and &lt;code&gt;const&lt;/code&gt;.  Both help with issues around variable scoping&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;, but the difference between the two can seem rather confusing.  It seems like &lt;code&gt;const&lt;/code&gt; might indicate a constant value that can&amp;rsquo;t be changed.  But mutable values declared with const can in fact change:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; arr &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; [&lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;, &lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt;, &lt;span style=&#34;color:#bd93f9&#34;&gt;3&lt;/span&gt;];
arr.push(&lt;span style=&#34;color:#bd93f9&#34;&gt;4&lt;/span&gt;);
console.log(arr) &lt;span style=&#34;color:#6272a4&#34;&gt;// [1, 2, 3, 4]
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Instead &lt;code&gt;const&lt;/code&gt; is once again about memory and reference assignment.  A variable that is assigned through const can&amp;rsquo;t be reassigned to a new location in memory.  So if it is pointed to a primitive like &lt;code&gt;123&lt;/code&gt; or &lt;code&gt;true&lt;/code&gt;, it truly is a constant, because the value can&amp;rsquo;t change. But when it&amp;rsquo;s pointed to a mutable value, it&amp;rsquo;s reference won&amp;rsquo;t change, and it will always &lt;code&gt;===&lt;/code&gt; any variables that have been assigned to it, but the actual contents of that memory can change.&lt;/p&gt;
&lt;h3 id=&#34;feedback-is-lovely&#34;&gt;Feedback is lovely&lt;/h3&gt;
&lt;p&gt;This is a new series, and I&amp;rsquo;d love to hear whether it is helpful for you, and any other topics you&amp;rsquo;d like to see covered. Feel free to reach out on &lt;a href=&#34;https://twitter.com/_benmccormick&#34;&gt;Twitter&lt;/a&gt; or &lt;a href=&#34;mailto:ben@benmccormick.org&#34;&gt;email&lt;/a&gt;&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;A topic for a different post&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;My carrier pidgeons have all fled their coop. I do promise that if you send me smoke signals I will sit back and ponder their meaning. Right after calling the fire department.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>JavaScript Proposals In Production</title>
      <link>https://benmccormick.org/2018/03/15/190000.html</link>
      <pubDate>Thu, 15 Mar 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/03/16/190000.html</guid>
      <description>&lt;p&gt;&lt;em&gt;This post was adopted from a twitter thread that outgrew it&amp;rsquo;s medium today.  You can see the original thread &lt;a href=&#34;https://twitter.com/_benmccormick/status/974670479905705984&#34;&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;This morning I saw the following tweet:&lt;/p&gt;
&lt;blockquote class=&#34;twitter-tweet&#34; data-lang=&#34;en&#34;&gt;&lt;p lang=&#34;en&#34; dir=&#34;ltr&#34;&gt;*TC39 proposes Array.flatten feature that breaks code that was working fine for 10 years*&lt;br&gt;&amp;quot;IT&amp;#39;S THEIR FAULT FOR DOING NONSTANDARD STUFF&amp;quot;&lt;br&gt;&lt;br&gt;*TC39 proposes changing classes feature not yet in standard*&lt;br&gt;&amp;quot;IT&amp;#39;S NOT FAIR I WROTE CODE USING THAT&amp;quot;&lt;/p&gt;&amp;mdash; Dave Methvin (@davemethvin) &lt;a href=&#34;https://twitter.com/davemethvin/status/974037352384430080?ref_src=twsrc%5Etfw&#34;&gt;March 14, 2018&lt;/a&gt;&lt;/blockquote&gt;
&lt;p&gt;The tweet refers to &lt;a href=&#34;https://github.com/allenwb/js-classes-1.1&#34;&gt;this proposal&lt;/a&gt; for replacing a number of other proposals for augmenting JS&amp;rsquo;s current class syntax, as well as recent backlash on twitter over &lt;a href=&#34;https://github.com/tc39/proposal-flatMap/pull/56&#34;&gt;a proposal &lt;/a&gt; to not use flatten or flatmap for future JS standard syntax due to their previous use in mootools.&lt;/p&gt;
&lt;p&gt;Because people have been using Babel or other tools to transpile their code and use the proposed class syntax today, it would be frustrating for many devs if the proposal shifted under them.  I&amp;rsquo;ve been there.  And thus, story time:&lt;/p&gt;
&lt;p&gt;A few years ago I used a polyfill for a browser API that wasn’t yet fully supported in all browsers.  And I used it in production code.  Browser support didn&amp;rsquo;t pick up nearly as quickly as I expected, and then the spec changed.  Supporting that code has caused me problems repeatedly since, and there isn&amp;rsquo;t a lot of support, given that the syntax isn&amp;rsquo;t standardized.  Because &lt;a href=&#34;https://benmccormick.org/2018/01/07/large-improvements-small-team/&#34;&gt;I am working with limited resources&lt;/a&gt; I  still haven’t been able to get rid of the polyfill code completely.  It&amp;rsquo;s baked into one of the most critical portions of my production application.  And so I&amp;rsquo;ve had to live with it and deal with some of it&amp;rsquo;s non-ideal aspects for a long time.  Since then I’ve avoided putting anything in production that isn’t in a spec.  And I have absolutely no regrets about that.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The lesson I’ve learned:&lt;/strong&gt; Polyfilling a partially supported spec for compatibility is fine.  Playing around with new proposals is fine (and actually a great idea if you want to influence the future of the language).  But I never want to use polyfills/transpiling for a &lt;em&gt;proposed spec&lt;/em&gt; in production code. And yes that means no decorators/class properties/pipeline operators in my code for now.  But that&amp;rsquo;s ok.  JavaScript is a pretty decent language today.  A little patience will help you in the end.  Even libraries like MobX that encourage the use of &amp;ldquo;future specs&amp;rdquo; will still work without them if they&amp;rsquo;re reasonably well maintained.&lt;/p&gt;
&lt;h3 id=&#34;why-does-this-happen&#34;&gt;Why Does This Happen?&lt;/h3&gt;
&lt;p&gt;To some folks the lesson of &amp;ldquo;Don&amp;rsquo;t use language features that aren&amp;rsquo;t standardized yet&amp;rdquo; probably looks obvious.  So why does this happen? I think there’s a community/culture aspect to some of this.  For instance, many of the early adopters of React really wanted to push the language forward to achieve better developer experience, and were more likely to propose and advocate for new syntax.  This was fine for them, because many of these folks were either&lt;/p&gt;
&lt;p&gt;a. Employees at large companies who had the resources to support whatever code extensions they wanted, and dedicate time to a large refactor if they got it wrong (not typical of most devs)
b. Consultants/teachers who are always trying to stay on the bleeding edge for teaching purposes and who don&amp;rsquo;t build projects intended to be maintained long term (not typical of most devs)
c. Involved in the language standards process and experimenting with new syntax for the purpose of influencing the language, rather than writing production code with it (not typical of most devs)&lt;/p&gt;
&lt;p&gt;Because of this, the need to compile JS for JSX purposes anyway and the heavy emphasis in the early React community on rethinking best practices, I&amp;rsquo;ve seen a lot more of this type of pre-standardization use of features in the React community than elsewhere.  The Ember community for instance doesn&amp;rsquo;t seem to have the same problems. But it started with early adopters in React, and spread when folks who were less informed about the standards process cargo-culted the code examples.  So here we are.&lt;/p&gt;
&lt;h3 id=&#34;my-suggestions&#34;&gt;My suggestions&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Learn about the ECMAScript standards process.&lt;/strong&gt;  &lt;a href=&#34;https://benmccormick.org/2017/07/10/how-to-follow-the-javascript-roadmap/&#34;&gt;This post&lt;/a&gt; can get you started.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Don&amp;rsquo;t use non-standard code in production.&lt;/strong&gt;  It just isn&amp;rsquo;t worth the headaches you may get later.&lt;/li&gt;
&lt;/ol&gt;
</description>
    </item>
    
    <item>
      <title>Weekly Links: March 16th</title>
      <link>https://benmccormick.org/2018/03/15/weekly-links-march.html</link>
      <pubDate>Thu, 15 Mar 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/03/16/weekly-links-march.html</guid>
      <description>&lt;h3 id=&#34;javascript-and-the-web&#34;&gt;JavaScript And The Web&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://hph.is/coding/bitmasks-react-context&#34;&gt;Bitmasks and the new React Context API | Haukur Hallvarðsson&lt;/a&gt; - A nice rundown of one aspect of the new React Context API that is likely to be familiar to low-level developers but will probably be a new idea to many front end devs: using bitmasks to test a condition.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://medium.com/@mweststrate/mobx-4-better-simpler-faster-smaller-c1fbc08008da&#34;&gt;MobX 4: Better, simpler, faster, smaller | Michel Weststrate&lt;/a&gt; - MobX continues to be a fantastic state management libary and this update looks like it will make it even better.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://engineering.linkedin.com/blog/2018/03/how-we-built-the-same-app-twice-with-preact-and-glimmerjs&#34;&gt;Lighter than Lightweight: How We Built the Same App Twice with Preact and Glimmer.js | LinkedIn Engineering&lt;/a&gt; - This is a really cool real world comparison of 2 JavaScript frameworks, where they actually built the same app in 2 separate frameworks, with core contributors to each framework involved in the implementation.  To be honest, my main takeaway is that among modern frameworks &amp;ldquo;framework performance&amp;rdquo; can be a bit overrated, and not a great reason to choose a specific library or framework, as compared to factors like developer experience, community, and fit with the existing codebase.&lt;/p&gt;
&lt;h3 id=&#34;rust-and-webassembly&#34;&gt;Rust And WebAssembly&lt;/h3&gt;
&lt;p&gt;I&amp;rsquo;ve been thinking about taking the time to learn a new language for the first time in a while.  I think WebAssembly and Rust transpiled to WebAssembly in particular are going to become an important part of high performance JavaScript applications and frameworks/libraries.  So I&amp;rsquo;m starting to check it out.  Here are a few  recent relevant links&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://hacks.mozilla.org/2018/03/making-webassembly-better-for-rust-for-all-languages/&#34;&gt;Making WebAssembly better for Rust &amp;amp; for all languages – Mozilla Hacks – the Web developer blog&lt;/a&gt; - This outlines a plan to improve the developer experience of what I think is the future of WebAssembly in most web apps: interop with JavaScript to improve performance of open source libraries and some core performance sensitive code.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/atom/xray&#34;&gt;GitHub - atom/xray: An experimental next-generation Electron-based text editor&lt;/a&gt; - A non-webassembly example of using Rust selectively to increase performance of an application built primarily using web technologies.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.rust-lang.org/2018/03/12/roadmap.html&#34;&gt;Rust&amp;rsquo;s 2018 Roadmap | Rust Blog&lt;/a&gt; - A good rundown of the areas of focus for Rust this year.  I&amp;rsquo;m particularly interested in their target use cases, since 3 of them (CLI tools, Network Services and WebAssembly/the web) are things that I have built before and will build again.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Classic Book Review: The Visual Display of Quantitative Information</title>
      <link>https://benmccormick.org/2018/03/12/190000.html</link>
      <pubDate>Mon, 12 Mar 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/03/13/190000.html</guid>
      <description>&lt;p&gt;If you have any interest at all in data visualization, you can&amp;rsquo;t get very far learning about it without hearing the name Edward Tufte.  His four books on the subjects have had a huge influence on the industry over the last 35 years, a time where data visualization has blossomed as it has moved from a tedious hand drawn task to a computer assisted activity that even middle schoolers can attempt with the software available on most laptops.&lt;/p&gt;
&lt;p&gt;Tufte&amp;rsquo;s first book, &lt;a href=&#34;http://amzn.to/2H6EB2f&#34;&gt;The Visual Display of Quantitative Information&lt;/a&gt; is also his most well known and acclaimed book&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.  It lays out many of the principles that he would go to expand on elsewhere:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Focus on the data&lt;/li&gt;
&lt;li&gt;&amp;ldquo;Graphical excellence is that which gives to the viewer the greatest number of ideas in the shortest time with the least ink in the smallest space&amp;rdquo;&lt;/li&gt;
&lt;li&gt;Graphics should have &lt;em&gt;integrity&lt;/em&gt;.  They shouldn&amp;rsquo;t mislead the reader.&lt;/li&gt;
&lt;li&gt;Remove unecessary clutter&lt;/li&gt;
&lt;li&gt;&lt;em&gt;and more&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The book is also beautiful.  Tufte chose to self-publish it so that he could control the exact layout and typography.  He also mixes in many old hand drawn visualizations to mix with a fewer new computer assisted graphics.  The result is stunning, and makes for a very enjoyable read throughout, as there is always something interesting to look at.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;typical_page.jpg&#34; alt=&#34;A typical page&#34;&gt;&lt;/p&gt;
&lt;p&gt;I was pleased to find that the book didn&amp;rsquo;t back up some of my own pre-conceived notions about Tufte and his work.  When I&amp;rsquo;ve seen him referenced in the past, it has been almost solely in terms of minimalism.  He was an expert witness for fewer colors, fewer lines, less ink.  But his takes here are more nuanced.  He definitely tends towards minimalism, and argues for reducing graphs to their bare minimum ink amount over conforming to familiar forms&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;.  But his go to example of great data display throughout the book is hardly minimalist.  Minard&amp;rsquo;s map of Napoleon invading Russia is a complex visualization that tracks the size of an army, time, location and temperature, all in a single image.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;minards-map.png&#34; alt=&#34;Minards Map of Napoleon Invading Russia&#34;&gt;&lt;/p&gt;
&lt;p&gt;Instead Tufte is really arguing for data efficiency.  Simple things should be displayed simply.  If you have a single number, don&amp;rsquo;t dress it up in a fancy graph.  Just show the number.  If you have a series of numbers, a table or simple scatter will work fine, no need for a fancy piece of chart &amp;ldquo;art&amp;rdquo;.  But when you have truly complex data, a complex visualization can make it accessible in ways that a large page of words and numbers never could on its own.&lt;/p&gt;
&lt;p&gt;I found &lt;a href=&#34;http://amzn.to/2H6EB2f&#34;&gt;The Visual Display of Quantitative Information&lt;/a&gt; fun, informative and inspirational.  If you work with data and have never read it, I&amp;rsquo;d definitely recommend checking it out.&lt;/p&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;Amazon named it one of the 100 Best Non-Fiction books of the 20th century&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;Some of that may be a relic of this book being originally written in the 80s before computers, his own work and the work of other similar thinkers greatly increased public awareness of data visualization standards like line and bar charts.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>Weekly Links: March 11th</title>
      <link>https://benmccormick.org/2018/03/10/weekly-links-march.html</link>
      <pubDate>Sat, 10 Mar 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/03/11/weekly-links-march.html</guid>
      <description>&lt;p&gt;Rather than posting random stuff that popped up this week like usual, I wanted to instead post a set of &amp;ldquo;classic&amp;rdquo; links instead. The theme this week is Learning React.  Here are some of the links that helped me to learn different React concepts as I was first tackling it.  Note that these are links that helped me learn the concepts behind different parts of the React ecosystem.  Some are intro level, while some assume basic familiarity with the concepts they discuss.&lt;/p&gt;
&lt;h3 id=&#34;the-motivation-behind-react&#34;&gt;The Motivation Behind React&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://reactjs.org/docs/thinking-in-react.html&#34;&gt;Thinking In React&lt;/a&gt; - It&amp;rsquo;s strange, but I never expect the official docs for a project to be the best explanation of their purpose.  Official documentation tends to lean towards the &amp;ldquo;how&amp;rdquo; rather than the &amp;ldquo;why&amp;rdquo;, and the motivations of the maintainers aren&amp;rsquo;t always the motivations of the community anyway.  But this article from the React docs remains the best explanations of the problems that React is solving as well as the way that it solves them.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://rauchg.com/2015/pure-ui&#34;&gt;Pure UI&lt;/a&gt; - Even moreso than &lt;em&gt;Thinking in React&lt;/em&gt;, this 2015 article nails the paradigm shift that React represented.  The power of UI as a function of data has been the biggest change I&amp;rsquo;ve experienced in my career building UIs, and this article was like a message in the bottle from the future when it was first written 3 years ago.&lt;/p&gt;
&lt;h3 id=&#34;flux-mobx-and-redux&#34;&gt;Flux, MobX and Redux&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://code-cartoons.com/a-cartoon-guide-to-flux-6157355ab207&#34;&gt;A cartoon guide to Flux | Lin Clark&lt;/a&gt; - This was a nice early run through of the Flux concepts.  Lin Clark is one of the best &amp;ldquo;front end explainers&amp;rdquo; out there, and she does a good job here.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://hackernoon.com/the-fundamental-principles-behind-mobx-7a725f71f3e8&#34;&gt;The Fundamental Principles Behind MobX | Michael Weststrate&lt;/a&gt; - Like most of the other links here, this is a theory link, not a practical introduction.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://egghead.io/courses/getting-started-with-redux&#34;&gt;Getting Started With Redux | Dan Abramov on Egghead.io &lt;/a&gt; - Like &lt;em&gt;Thinking with React&lt;/em&gt;, this is a great introduction to a library that starts with the problems to be solved and shows how a new library solves that problem, rather than simply telling you what a tool does.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://medium.com/@dan_abramov/you-might-not-need-redux-be46360cf367&#34;&gt;You Might Not Need Redux | Dan Abramov&lt;/a&gt; - Another helpful article for understanding what Redux is and isn&amp;rsquo;t solving for, helpful if you&amp;rsquo;re trying to decide whether to include it in a project.&lt;/p&gt;
&lt;h3 id=&#34;react-patterns&#34;&gt;React Patterns&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://egghead.io/courses/advanced-react-component-patterns&#34;&gt;Advanced React Component Patterns | Kent C Dobbs on Egghead.io&lt;/a&gt; - This is my one paid content link, but its so good that its worth sharing.  This was a fantastic course that covers patterns like Higher Order Components, Render props and more.  It discusses both the implementation concerns and motivation behind each.&lt;/p&gt;
&lt;h3 id=&#34;future-stuff&#34;&gt;Future Stuff&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://medium.com/dailyjs/reacts-%EF%B8%8F-new-context-api-70c9fe01596b&#34;&gt;React&amp;rsquo;s New Context API | Kent C Dobbs&lt;/a&gt; - This is fairly recent, but Kent Dobbs gave a great explanation of React&amp;rsquo;s new context API&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://reactjs.org/blog/2018/03/01/sneak-peek-beyond-react-16.html&#34;&gt;Sneak Peek: Beyond React 16 | React Blog&lt;/a&gt; - I posted this last week as well, but this is a great inspirational talk on where React is going next.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Weekly Links: March 2nd</title>
      <link>https://benmccormick.org/2018/03/01/weekly-links-march.html</link>
      <pubDate>Thu, 01 Mar 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/03/02/weekly-links-march.html</guid>
      <description>&lt;h3 id=&#34;javascript-and-the-web&#34;&gt;JavaScript And The Web&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://reactjs.org/blog/2018/03/01/sneak-peek-beyond-react-16.html&#34;&gt;Sneak Peek: Beyond React 16| React Blog&lt;/a&gt; - This is a preview of where React is going next.  I&amp;rsquo;m still processing through this, and how I can use it, but Suspense seems like something that will make dealing with async data much easier in React.  Loading states are something I deal with all the time, and having cleaner primitives for expressing them will be a big win.&lt;/p&gt;
&lt;h3 id=&#34;programming-tools&#34;&gt;Programming Tools&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;http://www.olioapps.com/blog/the-lost-art-of-the-makefile/&#34;&gt;The Lost Art of the Makefile |Jesse Hallett&lt;/a&gt; - An interesting case for using Makefiles to manage modern JavaScript builds on projects that don&amp;rsquo;t need the overhead of webpack.  I don&amp;rsquo;t think this is going to be the next trend in JS, but I am interested to see where the JS world leans next when it comes to task automation.  When I started using JS, I saw people using Make or tools from other language ecosystems to build projects.  Grunt and Gulp really changed that and moved folks towards using the node ecosystem for task automation.  Now the community seems to have settled on webpack for build related tasks, and npm scripts for everything else.  I&amp;rsquo;m all good with webpack for builds, it&amp;rsquo;s complicated but powerful.  But npm scripts are frustrating as a task automation solution.  There&amp;rsquo;s no ability to comment, and long operations in nested JSON strings are a bit unwieldy.  I&amp;rsquo;d love to see some standardization on something more like make that allows comments and powerful task composition.&lt;/p&gt;
&lt;h3 id=&#34;computer-science-in-js&#34;&gt;Computer Science In JS&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;http://raganwald.com/2018/02/23/forde.html&#34;&gt;Forde’s Tenth Rule, or, “How I Learned to Stop Worrying and ❤️ the State Machine” | Reginald Braithwaite&lt;/a&gt; - A really nice explanation of state machines, and how they can be used in JavaScript development.  The article is written at a very conceptual level and really explains the topic well.  I was thinking afterwards about how the state machine concepts reminded me of Redux, and fortunately I found another link that expanded on that connection&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://medium.freecodecamp.org/how-to-model-the-behavior-of-redux-apps-using-statecharts-5e342aad8f66&#34;&gt;How to model the behavior of Redux apps using statecharts | Luca Matteis&lt;/a&gt; - I hadn&amp;rsquo;t heard of statecharts before reading this, but they look like a really interesting tool for talking about large systems.  I&amp;rsquo;d be really curious to play with the redux middleware for automatically generating them and see if the artifacts it produces are useful.&lt;/p&gt;
&lt;h3 id=&#34;non-tech&#34;&gt;Non-Tech&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://mobile.nytimes.com/2018/02/23/opinion/eyesight-going-blind.html&#34;&gt;Am I Going Blind? | Frank Bruni&lt;/a&gt; - This is absurdly well written, and it hit me personally since the idea of going blind has always been a personal fear of mine.  I think everybody has their one bad thing that they irrationally fear will happen to them and this is mine.  The article was good perspective in mutliple ways, reminding me how blessed I am and how resilient humans (and our bodies) are.  (Via &lt;a href=&#34;https://daringfireball.net/linked/2018/02/23/bruni-going-blind&#34;&gt;Daring Fireball&lt;/a&gt;)&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Weekly Links: February 23rd</title>
      <link>https://benmccormick.org/2018/02/22/weekly-links-february.html</link>
      <pubDate>Thu, 22 Feb 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/02/23/weekly-links-february.html</guid>
      <description>&lt;h3 id=&#34;javascript-and-the-web&#34;&gt;JavaScript And The Web&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;http://2ality.com/2018/02/ecmascript-2019.html&#34;&gt;Feature watch: ECMAScript 2019 | 2ality&lt;/a&gt; - Not a lot to see here yet, but Axel Rauschmayer has set up a page for tracking the status of the next version of ECMAScript as features advance to stage 4 and become confirmed for the next version of the spec.  No features have been confirmed yet, but worth a bookmark.  He also has links to his detailed articles about the various candidate features if you&amp;rsquo;re interested in seeing where JavaScript is headed next.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.troyhunt.com/the-javascript-supply-chain-paradox-sri-csp-and-trust-in-third-party-libraries/&#34;&gt;The JavaScript Supply Chain Paradox: SRI, CSP and Trust in Third Party Libraries | Troy Hunt&lt;/a&gt; - This is a great reminder on why including scripts from 3rd party domains is a risky business, and how to do it securely.&lt;/p&gt;
&lt;h4 id=&#34;computer-science&#34;&gt;Computer Science&lt;/h4&gt;
&lt;p&gt;After my &lt;a href=&#34;https://benmccormick.org/2018/02/20/cs-for-fe/&#34;&gt;post on Computer Science&lt;/a&gt; this week, I thought I&amp;rsquo;d share 2 CS-y links I came across this week.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://medium.freecodecamp.org/i-dont-understand-graph-theory-1c96572a1401&#34;&gt;How to think in graphs: an illustrative introduction to Graph Theory and its applications | Vardan Grigoryan&lt;/a&gt; -  This is a nice &amp;ldquo;plain language&amp;rdquo; explanation of basic graph theory.  It&amp;rsquo;s a bit long, but it&amp;rsquo;s a nice thing to look at for the folks who told me this week they want to know more about data structures.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://amzn.to/2BL3YHo&#34;&gt;Learning JavaScript Design Patterns | Addy Osmani&lt;/a&gt; - One of the better &amp;ldquo;CS for front end&amp;rdquo; resources I&amp;rsquo;m aware of is Addy Osmani&amp;rsquo;s book on JavaScript design patterns.  Like a lot of things in JS land, parts of it haven&amp;rsquo;t aged well now that it&amp;rsquo;s a 6 year old book (it&amp;rsquo;s very focused on jQuery and DOM manipulation in many of its examples), but since it&amp;rsquo;s centered around more timeless design patterns, I think it holds up well.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Computer Science for Front End Developers?</title>
      <link>https://benmccormick.org/2018/02/19/190000.html</link>
      <pubDate>Mon, 19 Feb 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/02/20/190000.html</guid>
      <description>&lt;p&gt;I am primarily a front end web developer, and I have a Computer Science degree.  In my experience, this is neither rare nor particularly common.  Folks seem to get into front end dev because they&amp;rsquo;re trying to solve particular problems, and those problems exist whether you have a PhD in high performance computing or you&amp;rsquo;ve never written a line of code before.  Front end web development is how you make code real to people, and it is the minimal requirement for making something that people can actually interact with in a web browser.  As a result, a dizzying array of folks get into Front end dev, and you&amp;rsquo;ll find a broader set of experience levels than devs who work further &amp;ldquo;down the stack&amp;rdquo;.  All of which means that many front end devs have never had any sort of &amp;ldquo;formal&amp;rdquo; Computer Science education.&lt;/p&gt;
&lt;p&gt;Some CS degree holders turn up their nose at this, and it contributes to the reputation in some quarters of JavaScript and web dev not being &amp;ldquo;real programming&amp;rdquo;.  Some self-taught devs see themselves as being liberated from the &amp;ldquo;irrelevant theory&amp;rdquo; of formal Computer Science and see no need for that type of background for Front End development.  We all have the capacity to turn any sort of credential into a tribal mark.  My own experience is that developers can function just fine on the front end without a formal computer science background, but that my own education has helped me in my day to day work, mostly in subtle and indirect ways.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve been thinking for a while about what Computer Science topics are actually useful for front end developers.  It&amp;rsquo;s not obvious to me where to draw the lines, because you&amp;rsquo;ll never directly encounter many of the concepts that are covered in a typical Computer Science curriculum while making web applications. But I still have an intuition that my background in these subjects is helping me in my day to day.  This weekend I decided to ask Twitter about it.&lt;/p&gt;
&lt;blockquote class=&#34;twitter-tweet&#34; data-lang=&#34;en&#34;&gt;&lt;p lang=&#34;en&#34; dir=&#34;ltr&#34;&gt;Pondering what a blog series on “Computer Science for Front End Devs” would look like.  &lt;br&gt;&lt;br&gt;Thinking this would be a high level of “what you missed if you don’t have a CS degree”, focusing on a subset relevant to FE devs.&lt;br&gt;&lt;br&gt;Would love input.  What would you expect to be covered?&lt;/p&gt;&amp;mdash; Ben McCormick (@_benmccormick) &lt;a href=&#34;https://twitter.com/_benmccormick/status/965373638697463809?ref_src=twsrc%5Etfw&#34;&gt;February 18, 2018&lt;/a&gt;&lt;/blockquote&gt;
&lt;p&gt;I got a high degree of interest from that tweet, and so decided to keep digging into the idea.  I did some research into the typical structure of a modern Computer Science curriculum, and came up with the lists below. Depending on the school, certain topics may be elevated or diminished, grouped or split, but the general shape tends to look the same for most schools I&amp;rsquo;ve looked at.&lt;/p&gt;
&lt;h3 id=&#34;intro-class&#34;&gt;Intro class&lt;/h3&gt;
&lt;p&gt;Generally there is an intro class or 2 that can be skipped by students with previous experience that covers core programming concepts, usually with an Object-oriented philosophical tilt.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Programming basics&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Variables&lt;/li&gt;
&lt;li&gt;Basic Data Structures&lt;/li&gt;
&lt;li&gt;Control Structures/Recursion/Iteration&lt;/li&gt;
&lt;li&gt;Object Oriented Programming principles&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;core-curriculum&#34;&gt;Core Curriculum&lt;/h3&gt;
&lt;p&gt;There are also often 3-5 other &amp;ldquo;core&amp;rdquo; classes that all CS majors must take.  They generally break down something like this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Data Structures and Algorithms&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Big O analysis&lt;/li&gt;
&lt;li&gt;Common Data Structures - Linked Lists, Stacks, Queues Trees, Heaps, Graphs, etc&lt;/li&gt;
&lt;li&gt;Common Algorithms - Searches, Sorts, Graph algorithms, etc&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Computer Systems&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Start at the hardware level&lt;/li&gt;
&lt;li&gt;Assembly&lt;/li&gt;
&lt;li&gt;Compilers&lt;/li&gt;
&lt;li&gt;Memory Models&lt;/li&gt;
&lt;li&gt;Concurrency&lt;/li&gt;
&lt;li&gt;Operating Systems&lt;/li&gt;
&lt;li&gt;Processes&lt;/li&gt;
&lt;li&gt;File Systems&lt;/li&gt;
&lt;li&gt;Networking&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mathematical Foundations&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Proofs and logic&lt;/li&gt;
&lt;li&gt;Formal lanugages/Context Free Grammars/Turing Machines&lt;/li&gt;
&lt;li&gt;NP-Completeness&lt;/li&gt;
&lt;li&gt;Probability Theory&lt;/li&gt;
&lt;li&gt;Bayes Theorem&lt;/li&gt;
&lt;li&gt;Hashing&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Software Engineering (not always core)&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Architecture of larger programs&lt;/li&gt;
&lt;li&gt;Balancing risk/quality/cost&lt;/li&gt;
&lt;li&gt;Design Patterns&lt;/li&gt;
&lt;li&gt;Designing for security/robustness/scalability&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;potential-specialties&#34;&gt;Potential Specialties&lt;/h3&gt;
&lt;p&gt;Finally, programs usually have a selection of electives that students can take to dive deeper into different specialty areas.  These electives usually mirror the research interests of the faculty of the school but may include some of the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Systems Design&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Human-Computer Interaction&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Computer Networking&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Artificial Intelligence and Machine Learning&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Databases&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Computer Vision&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;computer-science-for-the-web&#34;&gt;Computer Science for the web&lt;/h2&gt;
&lt;p&gt;So how much of this is relevant to your average front end developer?  Some of it is more tightly tied to web programming than others.  Most of the basics will be picked up through osmosis for a typical front end dev, but a rigorous look at concepts like object-oriented programming and recursion might be beneficial.  While most can usually get by with simple data structures, a background in common &amp;ldquo;intermediate&amp;rdquo; data structures like stacks, trees, and graphs can be quite useful in day to day web dev.  Software Engineering principles are as obviously useful when building web sites as they are when you&amp;rsquo;re building firmware or operating systems. On the other hand, Computer Systems and Mathematical foundation concepts are usually not directly applicable in front end work.  In my own experience, they serve as useful background for understanding the abstractions that my day to day work is built on.  It&amp;rsquo;s good to have an intuition as to how browsers work, what is happening when we send data to a file, or what &amp;ldquo;text encoding&amp;rdquo; means.  And you may end up in a crazy situation where you need to understand the code behind Babel or V8, and knowledge of compilers becomes a real part of your job.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m trying to figure out the best way to teach some of this stuff to somebody who hasn&amp;rsquo;t and is never going to spend 4 years taking these classes.  So I&amp;rsquo;d love help from anyone reading:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;If you have a CS degree and write front end code, how has it helped you?&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;If you were going to try and share part of that education with somebody with different experiences, which parts would you say are important?  What resources would you recommend?&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;If you don&amp;rsquo;t have a CS degree, do you feel like you&amp;rsquo;re missing out on anything?  What useful-seeming concepts have you heard about but found it hard to find resources on?&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If you have any answers for those questions I&amp;rsquo;d love to hear from y&amp;rsquo;all on &lt;a href=&#34;https://twitter.com/_benmccormick&#34;&gt;Twitter&lt;/a&gt; or &lt;a href=&#34;mailto:ben@benmccormick.org&#34;&gt;email&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Weekly Links: February 16th</title>
      <link>https://benmccormick.org/2018/02/15/weekly-links-february.html</link>
      <pubDate>Thu, 15 Feb 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/02/16/weekly-links-february.html</guid>
      <description>&lt;h3 id=&#34;javascript-and-the-web&#34;&gt;JavaScript And The Web&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://staltz.com/promises-are-not-neutral-enough.html&#34;&gt;Promises are not neutral enough | André Staltz  &lt;/a&gt; - This is a pretty good dissection of the downsides of Promises as JavaScript&amp;rsquo;s default async primitive.  I&amp;rsquo;m glad that Promises have replaced callbacks as the default async method for most JavaScript code, but it does have the downside of making it harder for anything better to come along.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://css-tricks.com/direction-aware-hover-effects/&#34;&gt;Direction Aware Hover Effects | CSS-Tricks&lt;/a&gt; - As a relatively pedestrian CSS user, I always am fascinated by the cool things people can do with it.  These demos were no exception.  (Hat tip to &lt;a href=&#34;https://ponyfoo.com/weekly&#34;&gt;Ponyfoo&lt;/a&gt; for this one)&lt;/p&gt;
&lt;h3 id=&#34;tech-tools&#34;&gt;Tech Tools&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://abe-winter.github.io/plea&#39;s/help/2018/02/11/slack.html&#34;&gt;Slack is the opposite of organizational memory | Abe Winter&lt;/a&gt; - This is a fun rant that makes some good points.  I have a love/hate relationship with Slack.  It&amp;rsquo;s a fun tool that I enjoy using, but I&amp;rsquo;m not at all convinced that it&amp;rsquo;s really making me more productive. I definitely feel the pain of normalizing crazy short reply times, even though I thrive on that on some ways and love the dopamine hit of being instantly helpful to somebody.  Slack makes it easy to mistake noise for productivity, and I definitely agree that it is more ephemeral than it pretends to be.  But for all that&amp;hellip; I&amp;rsquo;m not sure there&amp;rsquo;s anything better out there&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;, especially for teams that work partially or completely remote.&lt;/p&gt;
&lt;h3 id=&#34;cryptocurrency-craziness&#34;&gt;Cryptocurrency Craziness&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://shkspr.mobi/blog/2018/02/advertising-screens-hacked-to-mine-bitcoin/&#34;&gt;Advertising Screens Hacked To Mine BitCoin | Terence Eden&lt;/a&gt; - This is just nuts.  Bitcoin seems to be enabling a whole new malware economy.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://techcrunch.com/2018/02/13/salon-coinhive-cryptocurrency-mining/&#34;&gt;Salon’s Monero mining project might be crazy like a fox | TechCrunch&lt;/a&gt; - At least some folks are giving you an ad-free malware experience though.&lt;/p&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;The truth of this statement of course is going to depend on what exactly you&amp;rsquo;re hoping Slack will do for you.  I consider Slack to be a communication tool and not a project management tool.  The linked article seems to conflate the two, which is maybe part of the problem here.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>Book Review: Clean Architecture</title>
      <link>https://benmccormick.org/2018/02/13/190000.html</link>
      <pubDate>Tue, 13 Feb 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/02/14/190000.html</guid>
      <description>&lt;p&gt;&lt;a href=&#34;http://amzn.to/2mKoejo&#34;&gt;Clean Architecture&lt;/a&gt; by Robert &amp;ldquo;Uncle Bob&amp;rdquo; Martin was one of the better books on Software Development I&amp;rsquo;ve read in recent years.  It did exactly what I want from a software book in 2018: it tackled an important high level topic with a great amount of depth in a way that helped me as a reader to develop insight and perspective on the topic.  These days blog posts and other online sources cover most of my &amp;ldquo;how to&amp;rdquo; needs, as well as the simple &amp;ldquo;what is X and why should I care about it&amp;rdquo; questions that I used to go to books for.  But there is still no substitute for books when you want an in depth understanding of an important broad topic.
&lt;a href=&#34;https://www.amazon.com/Clean-Architecture-Craftsmans-Software-Structure/dp/0134494164/ref=as_li_ss_il?ie=UTF8&amp;qid=1516226851&amp;sr=8-1&amp;keywords=clean+architecture&amp;linkCode=li2&amp;tag=benmccormicko-20&amp;linkId=c599845decc4e5ed1457acae2a375ad6&#34; target=&#34;_blank&#34;&gt;
&lt;img border=&#34;0&#34; class=&#34;inline-img&#34; src=&#34;//ws-na.amazon-adsystem.com/widgets/q?_encoding=UTF8&amp;ASIN=0134494164&amp;Format=_SL160_&amp;ID=AsinImage&amp;MarketPlace=US&amp;ServiceVersion=20070822&amp;WS=1&amp;tag=benmccormicko-20&#34; &gt;&lt;/a&gt;&lt;img  src=&#34;https://ir-na.amazon-adsystem.com/e/ir?t=benmccormicko-20&amp;l=li2&amp;o=1&amp;a=0134494164&#34; width=&#34;1&#34; height=&#34;1&#34; border=&#34;0&#34; alt=&#34;&#34; style=&#34;border:none !important; margin:0px !important;&#34; /&gt;
For this book, that topic is software architecture.  The book tackles it by starting with some history, and then starting with a micro view before expanding out its gaze.  After giving a broad overview of the different software paradigms, Martin walks readers through 3 levels of architecture principles: class-level design principles, component-level component principles and system-level architecture principles.  At each level he shows the similarities between the lower level principles, as well as the unique concerns at each scale. Then he wraps it up with a case study example that shows the principles discussed throughout the book in action.&lt;/p&gt;
&lt;p&gt;I found Clean Architecture to be a great reminder of concepts I learned in school&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; that I didn&amp;rsquo;t properly appreciate at the time due to a lack of practical experience.  It brought home to me that while there are some architectural things I do pretty well right now, like keeping code separated enough that it only has one reason to change, there are other things that I don&amp;rsquo;t do well a lot of the time.  For me the biggest realization was how much grief I&amp;rsquo;ve caused myself the last few years from failing to keep high level policies from depending on low level details.  The book gave me a few new lenses to examine my decisions with, and definitely inspired me to spend more time taking a step back to see the big picture as I&amp;rsquo;m adding new features.&lt;/p&gt;
&lt;p&gt;For me, that sense of perspective was the biggest win, but if you&amp;rsquo;re looking for detailed &amp;ldquo;how tos&amp;rdquo;, there&amp;rsquo;s a decent amount of that as well.  Martin goes into details about how to arrange and refactor classes to create maintainable systems that are easy to change, as well as identifying patterns to look for that may be a sign of problems to come.  He goes pretty deep into the weeds with examples and class diagrams as he discusses creating proper system boundaries and pulls it all together with a nice case study example at the end.&lt;/p&gt;
&lt;p&gt;While I did find Clean Architecture extremely helpful overall, I do have some nitpicks.  The biggest for me personally is that while the book mentions dynamic languages like Ruby and Python a few times, it mostly does so in passing to say that the principles mention still apply, but may look different.  Since this is usually not expanded upon, and all of the examples given seem to assume static languages that provide abstract interfaces to classes, it is sometimes hard to see how the books principles should be applied to the dynamic languages that I use daily.  I would love to have seen more detail there.  Also, the final chapter of the book &amp;ldquo;The Missing Chapter&amp;rdquo; was a bit of an oddity.  It was written by a different author&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;, framed issues that had already been covered differently, and came to some different conclusions than the rest of the book.  It was almost a counterpoint to the other parts of the book, which could have been interesting, but lacked an introduction or context to help explain its purpose.  Overall it left me a bit confused and ended the book on a discordant note rather than bringing the ideas together and focusing me on the important ideas.&lt;/p&gt;
&lt;p&gt;I can recommend &lt;a href=&#34;http://amzn.to/2mKoejo&#34;&gt;Clean Architecture&lt;/a&gt; for anyone who wants to get better at thinking about the big picture when it comes to software systems, particularly if you haven&amp;rsquo;t already been exposed to any of the theory behind designing maintainable systems.  If you&amp;rsquo;re usually working in static languages on larger projects, I would double that recommendation, as you&amp;rsquo;ll be right in the book&amp;rsquo;s wheelhouse.  For those like me working with dynamic languages on web projects, it may be a bit more hit or miss, but it still is a great way to broaden your horizons and gain some new ways of thinking about the tradeoffs our work entails.&lt;/p&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;I was a Computer Science major, but if you weren&amp;rsquo;t exposed to theories of software architecture through a curriculum&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;This was not obvious to me on first reading, I only went back and noticed the acknowledgement on the chapter page when I was confused by a 3rd person reference to the author.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>Weekly Links: February 9th</title>
      <link>https://benmccormick.org/2018/02/08/weekly-links-february.html</link>
      <pubDate>Thu, 08 Feb 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/02/09/weekly-links-february.html</guid>
      <description>&lt;h3 id=&#34;javascript-and-the-web&#34;&gt;JavaScript And The Web&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;http://codemirror.net/&#34;&gt;CodeMirror&lt;/a&gt; - CodeMirror is a JavaScript library for building text/code editors in the browser.  It isn&amp;rsquo;t new, but I&amp;rsquo;ve had the pleasure of building something moderately complex with it over the past week, and thought it deserved some promotion.  It makes building an online editor that does shiny &amp;ldquo;text editor&amp;rdquo; things like linting, find and replace, syntax highlighting and autocomplete a very manageable endeavor.  It&amp;rsquo;s highly extendable and is a nice example of &amp;ldquo;easy things should be easy and hard things should be possible&amp;rdquo;, with simple addons for basic stuff, and less simple extension points for custom work.  If you have need of an online text editor, make sure to check it out!&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://www.tomanthony.co.uk/blog/googlebot-javascript-random/&#34;&gt;Googlebot’s Javascript random() function is deterministic - Tom Anthony&lt;/a&gt; - A really interesting peek at a small part of how Googlebot actually functions when rendering and indexing the web.&lt;/p&gt;
&lt;h3 id=&#34;non-tech&#34;&gt;Non-Tech&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://medium.com/@pamelafox/sleep-strategies-for-a-racing-mind-d717e1ab890&#34;&gt;Sleep strategies for a racing mind – Pamela Fox&lt;/a&gt; - I&amp;quot;ve never had the easiest time falling asleep at night, and it&amp;rsquo;s taken me a long time to figure out the best ways to manage that.  This article lays out a bunch of strategies for coping, many of which are the same things I&amp;rsquo;ve had to learn the hard way.  If you struggle to sleep, definitely worth a read.&lt;/p&gt;
&lt;p&gt;Finally I&amp;rsquo;ll leave you with my personal pick for &amp;ldquo;tweet of the week&amp;rdquo;&lt;/p&gt;
&lt;blockquote class=&#34;twitter-tweet&#34; data-lang=&#34;en&#34;&gt;&lt;p lang=&#34;en&#34; dir=&#34;ltr&#34;&gt;If at first you don’t succeed... &lt;a href=&#34;https://twitter.com/hashtag/science?src=hash&amp;amp;ref_src=twsrc%5Etfw&#34;&gt;#science&lt;/a&gt; &lt;a href=&#34;https://t.co/2TGojKDcr3&#34;&gt;pic.twitter.com/2TGojKDcr3&lt;/a&gt;&lt;/p&gt;&amp;mdash; TwistedDoodles (@twisteddoodles) &lt;a href=&#34;https://twitter.com/twisteddoodles/status/960801583012380672?ref_src=twsrc%5Etfw&#34;&gt;February 6, 2018&lt;/a&gt;&lt;/blockquote&gt;
</description>
    </item>
    
    <item>
      <title>React Architecture Confessions</title>
      <link>https://benmccormick.org/2018/02/06/190000.html</link>
      <pubDate>Tue, 06 Feb 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/02/07/190000.html</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve been reading through &lt;a href=&#34;http://amzn.to/2mKoejo&#34;&gt;Clean Architecture&lt;/a&gt; by Robert &amp;ldquo;Uncle Bob&amp;rdquo; Martin this month&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;, and while it is great it has had the unpleasant effect of reminding me of all of the mistakes I&amp;rsquo;ve made over the past few years while learning and using &lt;a href=&#34;https://reactjs.org/&#34;&gt;React&lt;/a&gt;.  I&amp;rsquo;ve absolutely loved using React at work, and it has made so many things easier.  But it&amp;rsquo;s a very unopinionated tool when it comes to structuring applications, and I made a lot of mistakes as I was using it to build some small side projects, and then transitioned a major production app to React from Backbone/Marionette.  These mistakes are all architectural; how I broke out components, communicated between components, and managed data and dependencies within components.&lt;/p&gt;
&lt;p&gt;I thought it would be useful to lay out the architecture mistakes I made as I was learning React, both as a solid reflection exercise for myself, and a warning to those of you who are just starting down the &amp;ldquo;component based UI&amp;rdquo; road.&lt;/p&gt;
&lt;h3 id=&#34;my-mistakes&#34;&gt;My Mistakes&lt;/h3&gt;
&lt;h4 id=&#34;1-including-api-calls-directly-in-components&#34;&gt;1. Including API calls directly in components&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;What I did wrong&lt;/strong&gt;: This is an embarrassing one, but essentially in several places I had components directly fetching data from the server in their constructors or mount calls, and using that information to determine what to render.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why I did it&lt;/strong&gt;: This was to some extent a lack of planning.  I had all my core &amp;ldquo;business objects&amp;rdquo; modeled in some sort of separate object oriented way (either as Backbone or MobX objects) and was able to coordinate syncing them to the server outside of the component layer.  But some data in the system hadn&amp;rsquo;t been modeled in that way, and when I encountered a need for those components (such as some types of system configurations) instead of stepping back and coming up with a design for modeling those configurations on the front end, I instead sometimes fell back to an ad-hoc API call.   This was also sometimes a result of lazily copying legacy code that had bad patterns while converting components to React, and other developers copying bad patterns when trying to figure out the new React code.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What I should have done instead&lt;/strong&gt;: This could be a whole series of blog posts in itself, but essentially I should have been observing a few principles that would have set off alarm bells.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Components in a system of any size shouldn&amp;rsquo;t know about the server. UI Components are about as &amp;ldquo;low level detail&amp;rdquo; as it gets in a UI architecture, and should be passed the data they need from a higher level portion of the system.&lt;/li&gt;
&lt;li&gt;If the front end code needs data from the server, it is worth the time to properly model that data in terms of whatever data layer the front end is using.&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;2-breaking-the-props-as-the-component-interface-abstraction&#34;&gt;2. Breaking the &amp;ldquo;props as the component interface&amp;rdquo; abstraction&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;What I did wrong&lt;/strong&gt;: One of the best things about React is the clear interfaces components provide with their list of props.  If properly documented with PropTypes or a type system like Flow or Typescript, it&amp;rsquo;s easy to look at any React component and tell what data it expects to receive, and therefore how other code is expected to interact with it.  99% of the time, good React components act as a function of &lt;code&gt;(props, state) =&amp;gt; UI&lt;/code&gt;.  It is however, possible to get access to a component instance, and call functions on them.  There are  rare situations where this is the right way to do things, for instance &lt;a href=&#34;https://stackoverflow.com/questions/28889826/react-set-focus-on-input-after-render&#34;&gt;focusing an input&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;When I first started creating React components though, I overused that pattern, and accessed the interface directly to access or change its internal state.  I&amp;rsquo;d have components like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; SpecialInput &lt;span style=&#34;color:#ff79c6&#34;&gt;extends&lt;/span&gt; React.Component {
  constructor(props) {
    &lt;span style=&#34;color:#ff79c6&#34;&gt;super&lt;/span&gt;(props);
    &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.state &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {
      inputValue&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;abc&amp;#39;&lt;/span&gt;
    }
  }
  getValue() {
    &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.state.inputValue;
  }
  setValue(inputValue) {
    &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.setState({inputValue});
  }
  render() {
    &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;input
      className&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;fancy-input&amp;#39;&lt;/span&gt;
      defaultValue&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;{&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.state.inputValue}
      onChange&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;{inputValue =&amp;gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.setState({inputValue})}
    &lt;span style=&#34;color:#ff79c6&#34;&gt;/&amp;gt;&lt;/span&gt;;
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;that I would access from parent container like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;
&lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; InputUser

  methodThatGotCalledOnSomeEvent() {
    doSomethingWith(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.input.getValue())
  }

  render() {
    &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; (&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;div&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;
      &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;SpecialInput ref&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;{el =&amp;gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.input &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; el}&lt;span style=&#34;color:#ff79c6&#34;&gt;/&amp;gt;&lt;/span&gt;
    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;/div&amp;gt;);
  }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Why I did it&lt;/strong&gt;:  Early on I was using this pattern in a way that copied other frameworks I was familiar with.  A parent component would need the state of it&amp;rsquo;s child component, so it would maintain a reference to the child and query the child about the state.  When I converted Backbone components to React, sometimes I was basically just copy and pasting existing code, and making it work.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What I should have done instead&lt;/strong&gt;:  React doesn&amp;rsquo;t really encourage parents pulling state from their children.  Instead, if there is state that needs to be shared between components, it should be moved up to the parent component and then the state and an updater function should be passed down to the child component.  So my example above would look like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; SpecialInput &lt;span style=&#34;color:#ff79c6&#34;&gt;extends&lt;/span&gt; React.Component {
  render() {
    &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;input
      className&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;fancy-input&amp;#39;&lt;/span&gt;
      defaultValue&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;{&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.props.value}
      onChange&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;{event =&amp;gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.props.updateValue(event.target.value)}
    &lt;span style=&#34;color:#ff79c6&#34;&gt;/&amp;gt;&lt;/span&gt;;
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;that I would access from parent container like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;
&lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; InputUser &lt;span style=&#34;color:#ff79c6&#34;&gt;extends&lt;/span&gt; React.Component {
  constructor(props) {
   &lt;span style=&#34;color:#ff79c6&#34;&gt;super&lt;/span&gt;(props);
    &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.state &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {
      inputValue&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;abc&amp;#39;&lt;/span&gt;
    }
  }

  methodThatGotCalledOnSomeEvent() {
    doSomethingWith(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.state.inputValue)
  }

  render() {
    &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;div&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;
        &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;SpecialInput
             value&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;{&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.state.inputValue}
             updateValue&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;{inputValue =&amp;gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.setState({inputValue})}
          &lt;span style=&#34;color:#ff79c6&#34;&gt;/&amp;gt;&lt;/span&gt;
    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;/div&amp;gt;

  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;3-interacting-with-3rd-party-components-directly&#34;&gt;3. Interacting with 3rd party components directly&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;What I did wrong&lt;/strong&gt;: My first year and a half using React, when I was using 3rd party UI components like &lt;a href=&#34;https://github.com/facebookarchive/fixed-data-table&#34;&gt;react-fixed-data-table&lt;/a&gt; I would always use them directly in my components, and take full advantage of their APIs.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why I did it&lt;/strong&gt;: Because every React library in the world has documentation showing how to use its components directly in code for a variety of different use cases, and nobody ever tells you to put an abstraction around their code&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What I should have done instead&lt;/strong&gt;: I should have wrapped the 3rd party libraries in one or more wrapper components.  This has a few advantages:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;When we&amp;rsquo;re using a UI component like a table in a new place in our App, if I&amp;rsquo;ve created a wrapper component that has presets for most common settings, I only need to configure the things that are meaningful to this new use case in my app&lt;/li&gt;
&lt;li&gt;Targeted wrapper components like a &lt;code&gt;SortableTable&lt;/code&gt; component or a &lt;code&gt;DropdownWithAutoComplete&lt;/code&gt; component are easy to understand to a new reader of the code.  Instead of digging through configuration props, they can read the component name and understand the purpose of that component then focus on the data being passed to it&lt;/li&gt;
&lt;li&gt;When making updates to a library it is much easier to test that the changes are safe if the uses of the library are limited to a few focused components, rather than being spread across a whole application&lt;/li&gt;
&lt;li&gt;Similarly, if we need to switch to a new library, that is much easier with a limited footprint&lt;/li&gt;
&lt;li&gt;It can be easier to create reliable automatic tests using a wrapper component, since you have more control of things like how mocking works and when the component interface changes than you do for 3rd party code&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;4-importing-other-parts-of-the-system-directly-into-display-components&#34;&gt;4. Importing other parts of the system directly into display components&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;What I did wrong&lt;/strong&gt;: The main application I work on uses a messaging system to allow communication between different parts of the system.  It&amp;rsquo;s a legacy piece from when it existed as a Backbone application, and isn&amp;rsquo;t a very React-y way of doing things, but that isn&amp;rsquo;t really a problem.  This situation would be the same for a logging component or a data store.  What isn&amp;rsquo;t great is that when I need to use the messaging system, I always import it directly into the component file.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why I did it&lt;/strong&gt;: Direct imports are convenient, the messaging system is a core part of my system, and it seemed like a normal way of accessing it.  I also wasn&amp;rsquo;t aware of any better way to do it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What I should have done instead&lt;/strong&gt;:  The disadvantage of direct imports is that they&amp;rsquo;re harder to test.  If I had passed my messaging system as a prop to whatever component needed it, it would be much easier to test that it was called in the way I expected, without having to mock out the whole messaging system library.  I also could abstract away the whole power of the messaging system, and only provide the specific functionality needed by a component.  When I first began working on this system though, I didn&amp;rsquo;t know a practical way to do this.  The messenger system was often used by deeply nested components, and it seemed bad to pass it down a whole component tree.&lt;/p&gt;
&lt;p&gt;The answer is to use the &lt;a href=&#34;https://www.robinwieruch.de/react-provider-pattern-context/&#34;&gt;Provider pattern&lt;/a&gt;.  The provider pattern is a way to use React&amp;rsquo;s context API to provide top level properties from a high level parent component to deeply nested child components.  It is a perfect pattern for providing important high level pieces of your application to low level components without tightly coupling them, while maintaining testability.&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h4 id=&#34;5-changing-too-many-things-at-once&#34;&gt;5. Changing too many things at once&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;What I did wrong&lt;/strong&gt;: When my team began converting our application from Backbone to React, it was tempting to try and change many things at once.  All the React examples you see online are using Babel/ES6, Webpack, Redux, React Router and tons of other shiny but complicated things.  Trying to implement it all in an existing project&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt; can be overwhelming and lead to &lt;a href=&#34;http://mikehadlow.blogspot.com/2014/12/the-lava-layer-anti-pattern.html&#34;&gt;lava layers&lt;/a&gt;.  We actually started out with good discipline and converted files to use ES6 first, then added Webpack, then slowly started to convert UI components to React.  Unfortunately as we continued to convert React, we began replacing our Backbone data models with MobX, and began using CSS Modules in some places.  When our team size was reduced last year, we were left in a situation where the same functions were performed in different ways throughout the codebase.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why I did it&lt;/strong&gt;: It&amp;rsquo;s easy to see things that could be better in a web application and immediately want to fix them!  Especially if parts of that change seem easier than other changes you&amp;rsquo;re working on&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What I should have done instead&lt;/strong&gt;: I wrote about this &lt;a href=&#34;https://benmccormick.org/2018/01/07/large-improvements-small-team/&#34;&gt;at length&lt;/a&gt; last month, but there really is no substitute for taking things one at a time.  While it&amp;rsquo;s tempting to think that it will be easier to convert to React if you&amp;rsquo;re using other &amp;ldquo;react-y&amp;rdquo; tools and libraries, your code will ultimately be more maintainable if it is consistent throughout an application.  The only reliable way to do that is to make changes completely before you start making other changes.  It isn&amp;rsquo;t sexy, and it will leave you at least a little ways off the bleeding edge, but it&amp;rsquo;s the way to build large, reliable systems and keep them up to date.&lt;/p&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;At the time of writing this, it was super on sale on &lt;a href=&#34;http://amzn.to/2mKoejo&#34;&gt;Amazon&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;Note that the Context API that the provider pattern is based on is changing, so I&amp;rsquo;d isolating out any provider code you write into a reusable component so that it is easy to update later&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;Or even a new project for that matter!&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>Weekly Links: February 3rd</title>
      <link>https://benmccormick.org/2018/02/02/weekly-links-february.html</link>
      <pubDate>Fri, 02 Feb 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/02/03/weekly-links-february.html</guid>
      <description>&lt;h3 id=&#34;javascript-and-the-web&#34;&gt;JavaScript And The Web&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;http://2ality.com/2017/02/ecmascript-2018.html&#34;&gt;ECMAScript 2018 | 2ality&lt;/a&gt; - The spec for the 2018 version of &lt;a href=&#34;https://benmccormick.org/2015/09/14/es5-es6-es2016-es-next-whats-going-on-with-javascript-versioning/&#34;&gt;ECMAScript&lt;/a&gt; has been finalized and this is a good roundup of the new features and syntax available.  I&amp;rsquo;m personally excited for rest/spread properties to be an official part of the language.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://medium.com/@firt/pwas-are-coming-to-ios-11-3-cupertino-we-have-a-problem-2ff49fd7d6ea&#34;&gt;PWAs are coming to iOS 11.3: Cupertino, we have a problem | Maximiliano Firtman&lt;/a&gt; - Interesting look at what is and isn&amp;rsquo;t available in the newest version of Safari when it comes to PWAs and offline support&lt;/p&gt;
&lt;h3 id=&#34;tech-and-business&#34;&gt;Tech and Business&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://medium.com/99-mph/1-trillion-of-real-estate-is-on-the-move-heres-why-94ee9233e5eb&#34;&gt;1 Trillion of Real Estate is on the move | Phil Levin&lt;/a&gt; - Almost everybody seems to agree that self driving cars are going to happen.  It&amp;rsquo;s only a question of when.  But the other question is what the second-level effects of self driving cars will be.  Those who can correctly predict the answer to those two questions are going to have opportunities to make money and create interesting businesses. This is an interesting take on how self-driving cars might affect real estate.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Weekly Links: January 19th</title>
      <link>https://benmccormick.org/2018/01/18/weekly-links-january.html</link>
      <pubDate>Thu, 18 Jan 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/01/19/weekly-links-january.html</guid>
      <description>&lt;h3 id=&#34;javascript-and-the-web&#34;&gt;JavaScript And The Web&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://stackoverflow.blog/2018/01/11/brutal-lifecycle-javascript-frameworks/&#34;&gt;The Brutal Lifecycle of JavaScript Frameworks | Stack Overflow Blog&lt;/a&gt; - This was an interesting analysis on how JavaScript frameworks have risen and fallen.  Among the reasons that it&amp;rsquo;s interesting is that the data appears to be a bit of a Rorschach test.  The post itself is very negative about the pace of change in the JavaScript framework world.  But I saw a lot of twitter takes like this one:&lt;/p&gt;
&lt;blockquote class=&#34;twitter-tweet&#34; data-lang=&#34;en&#34;&gt;&lt;p lang=&#34;en&#34; dir=&#34;ltr&#34;&gt;This “new framework every 6-months” FUD is comical. The crux is centered on 4 JS frameworks released over the last decade. &lt;br&gt;&lt;br&gt;4. In 10 years. &lt;br&gt;&lt;br&gt;It’s great for my business, but makes me chuckle. &lt;br&gt;&lt;br&gt;It’s not really moving that fast y’all. &lt;a href=&#34;https://t.co/BiH7UK0M9V&#34;&gt;https://t.co/BiH7UK0M9V&lt;/a&gt;&lt;/p&gt;&amp;mdash; Joel ⛈ (@jhooks) &lt;a href=&#34;https://twitter.com/jhooks/status/951924735654244352?ref_src=twsrc%5Etfw&#34;&gt;January 12, 2018&lt;/a&gt;&lt;/blockquote&gt;
&lt;p&gt;Personally I lean more toward the side that there&amp;rsquo;s nothing wrong here.  The change in frameworks has come during a large change in use cases and technology used on the web.  Think PWAs verse server-side generated sites, and the large amount of new browser APIs and JavaScript language features.  These things have naturally brought new best practices which have been encoded in frameworks.  While it is true that a jQuery based site from 2009 might be difficult to maintain through today, that has less to do with the lack of support for the technology than it does with the fundamental nature of web development.  It would be much more difficult to build and scale a web application like &lt;a href=&#34;https://slack.com/&#34;&gt;Slack&lt;/a&gt; using only jQuery and other 2009 technologies.&lt;br&gt;
Which is why it was surpassed for &lt;em&gt;web application&lt;/em&gt; development first by a wave of frameworks that allowed you to model domain concepts in an object oriented way and tie that to a UI (Backbone, Angular1, Knockout), and then by a second wave that allowed you to do that with more declarative component-based UIs (React, Ember, Angular2+, Vue).  Those evolutions have come to match a real need.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://stackoverflow.com/questions/48270127/can-a-1-a-2-a-3-ever-evaluate-to-true/48274520#48274520&#34;&gt;Can (a ==1 &amp;amp;&amp;amp; a== 2 &amp;amp;&amp;amp; a==3) ever evaluate to true? | Stack Overflow&lt;/a&gt; - This was a fun little question.  I don&amp;rsquo;t think I like it as an interview question for JavaScript, since it borders on trivia, and requires in-depth knowledge of the &amp;ldquo;bad parts&amp;rdquo; of JavaScript like &lt;code&gt;==&lt;/code&gt; and &lt;code&gt;with&lt;/code&gt; or global variable behavior that many new developers are just taught to avoid.  But it&amp;rsquo;s definitely a fun trivia question.  And it may even be a good interview question in Python, where you can do it using more commonly accepted parts of the language.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;EqualToEverything&lt;/span&gt;:
  &lt;span style=&#34;color:#ff79c6&#34;&gt;def&lt;/span&gt; __eq__(self, x): &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;True&lt;/span&gt;
a &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; EqualToEverything()
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;print&lt;/span&gt;(a &lt;span style=&#34;color:#ff79c6&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;and&lt;/span&gt; a &lt;span style=&#34;color:#ff79c6&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;and&lt;/span&gt; a &lt;span style=&#34;color:#ff79c6&#34;&gt;==&lt;/span&gt;&lt;span style=&#34;color:#bd93f9&#34;&gt;3&lt;/span&gt;) &lt;span style=&#34;color:#6272a4&#34;&gt;#prints True&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;a href=&#34;https://hacks.mozilla.org/2018/01/making-webassembly-even-faster-firefoxs-new-streaming-and-tiering-compiler/&#34;&gt;Making WebAssembly even faster: Firefox’s new streaming and tiering compiler | Lin Clark&lt;/a&gt; - Web Assembly + Rust is quickly moving to the top of my &amp;ldquo;I&amp;rsquo;ve got to learn more about that&amp;rdquo; list.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://slack.engineering/keep-webpack-fast-a-field-guide-for-better-build-performance-f56a5995e8f1&#34;&gt;Keep webpack Fast: A Field Guide for Better Build Performance | Slack Engineering&lt;/a&gt; - This is a super helpful and detailed list of performance tips and tricks for Webpack builds, which unfortunately are easy to make slow and challenging to make fast for large projects.  Even after having my own fights with webpack last year, I learned a few things from this, and look forward to experimenting with them.&lt;/p&gt;
&lt;h3 id=&#34;tech-and-business&#34;&gt;Tech and Business&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://www.joelonsoftware.com/2018/01/12/birdcage-liners/&#34;&gt;Birdcage Liners | Joel Spoelsky&lt;/a&gt; - Joel&amp;rsquo;s first post in a while is a great piece on the problems with social media, as well as tech folks&#39; responsibility to think through the choices they&amp;rsquo;re making, including the secondary effects.  What type of future are we making?&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://motherboard.vice.com/en_us/article/9kng57/dogecoin-my-joke-cryptocurrency-hit-2-billion-jackson-palmer-opinion&#34;&gt;My Joke Cryptocurrency Hit $2 Billion and Something Is Very Wrong&lt;/a&gt; - I promise I snagged this link to post before bitcoin took a dip this week, but I don&amp;rsquo;t think it&amp;rsquo;s properly appreciated in many places just how crazy the cryptocurrency fad is becoming.  Meme-based joke currencies are being valued at billions of dollars, and there are many other similar newborn currencies with similar valuations out there.  I&amp;rsquo;m not going to try to give anyone investment advise, but it seems clear for now that at minimum these &amp;ldquo;currencies&amp;rdquo; are completely unusable for their theoretical purpose as currency given the price swings.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Weekly Links: January 12th</title>
      <link>https://benmccormick.org/2018/01/11/weekly-links-january.html</link>
      <pubDate>Thu, 11 Jan 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/01/12/weekly-links-january.html</guid>
      <description>&lt;h3 id=&#34;javascript-and-the-web&#34;&gt;JavaScript And The Web&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://egghead.io/courses/manage-application-state-with-mobx-state-tree&#34;&gt;Manage Application State with Mobx-state-tree| Michael Weststrate on Egghead&lt;/a&gt;  - Mobx-state-tree is an opinionated state library built on top of the unopinionated Mobx library.  This is a free course explaining why it exists and how to use it.  I &lt;a href=&#34;https://benmccormick.org/2017/01/09/mobx-first-impressions/&#34;&gt;wrote about Mobx last year&lt;/a&gt; and am still enjoying using it a year later.  I&amp;rsquo;m excited to dive into Mobx-state-tree and hopefully sharpen my Mobx skills in the process.&lt;/p&gt;
&lt;h3 id=&#34;programming-tools-and-practices&#34;&gt;Programming Tools And Practices&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;http://blog.atom.io/2018/01/10/the-state-of-atoms-performance.html&#34;&gt;The State of Atom’s Performance | Atom Blog&lt;/a&gt; - Atom continues to (slowly) become snappier.  I&amp;rsquo;m glad to see how organized they are on this.  It&amp;rsquo;s really hard to take something that was built with a slower architecture fast while it&amp;rsquo;s being used by tens of thousands of people every day.  They&amp;rsquo;re making great progress.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://amzn.to/2DqBeSQ&#34;&gt;Clean Architecture | Robert C Martin&lt;/a&gt; - I&amp;rsquo;ll probably be posting more on this soon, but I&amp;rsquo;ve been reading the new book on architecture by &amp;ldquo;Uncle Bob&amp;rdquo; Martin, and it&amp;rsquo;s fantastic.  It breaks down big architecture and program design concepts like the Single Responsibility Principle and Dependency Inversion, and explains them well individually, but also shows how they fit together when designing a large system.  I&amp;rsquo;ll write a full review when I finish the book, but for now just wanted to share that it is worth picking up.&lt;/p&gt;
&lt;h3 id=&#34;non-tech&#34;&gt;Non-Tech&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://www.nytimes.com/2018/01/09/us/north-carolina-gerrymander.html&#34;&gt;North Carolina Is Ordered To Redraw Its Congressional Map | NY Times&lt;/a&gt; - A little bit of local news here &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;, but it is still important for everyone in the USA.  Redistricting is the type of problem where a simple rules based algorithm could be helpful.  Nothing opaque or deep-learning-y, just have a machine apply a published set of rules and work with the results.&lt;/p&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;I&amp;rsquo;m a proud resident of Durham, North Carolina&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>Tips For Improving a Large Code Base With A Small Team</title>
      <link>https://benmccormick.org/2018/01/06/190000.html</link>
      <pubDate>Sat, 06 Jan 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/01/07/190000.html</guid>
      <description>&lt;p&gt;Over the last year I&amp;rsquo;ve been acting as the lone JavaScript resource working on a codebase with around 90k lines of JavaScript code.  That has left me spending the vast majority of my work time trying to knock out features and deal with bugs across the large code surface area.  But I&amp;rsquo;ve also wanted to do my best to continue to improve code quality with limited resources.  Here are a few things I&amp;rsquo;ve learned about trying to improve code quality across a large project with limited resources.&lt;/p&gt;
&lt;h4 id=&#34;1-you-need-to-accept-not-being-on-the-bleeding-edge&#34;&gt;1. You need to accept not being on the bleeding edge&lt;/h4&gt;
&lt;p&gt;Let&amp;rsquo;s be real, in the JavaScript world the only way to always be on the bleeding edge is to never maintain an application for more than a few weeks.  And even in other contexts, it often is much less feasible than hype bubbles at conferences or sites like Hacker News might make it seem.  Most companies that are shipping software that users actually pay for are using quite a lot of very old technology quite extensively.  That&amp;rsquo;s not to say there&amp;rsquo;s no place for new and shiny things, but there will always be limits to how new and shiny things get.  When you&amp;rsquo;re low on people resources for the size of your project, those limits get a lot more restrictive.&lt;/p&gt;
&lt;h4 id=&#34;2-its-important-to-identify-your-pain-points&#34;&gt;2. It&amp;rsquo;s important to identify your pain points.&lt;/h4&gt;
&lt;p&gt;There are 3 main type of value that developers can add by changing a software system. They can write new &lt;strong&gt;features&lt;/strong&gt;, which give users new capabilities.  They can improve some &lt;strong&gt;cross-feature attributes&lt;/strong&gt; of the system like loading speed, accessibility, design, logging or documentation.  Or they can make &lt;strong&gt;architecture improvements&lt;/strong&gt; that make it easier to make other changes.  Generally engineers don&amp;rsquo;t have to argue to add features, because the business decision makers will be calling for them constantly.  Cross-feature things like performance, design or logging sometimes come from business decision makers, but often only when things have become problematic, and then the conversations around how long it will take to achieve improvements can be tense ones.  Architecture concerns pretty much never come from business folks, because they usually don&amp;rsquo;t see the effects of a bad architecture until it is too late and shipping simple features has become a disastrously slow process&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.  It&amp;rsquo;s part of a developer&amp;rsquo;s job to push for the latter 2 type of changes when they&amp;rsquo;re needed.   But with limited resources, &lt;em&gt;needed&lt;/em&gt; is often hard to quantify.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s why it is important to know what is &lt;em&gt;actually&lt;/em&gt; causing you pain, or will soon be causing pain.  Is your site getting slower and slower?  Is your CSS a giant tangled mess that creates bugs with every change&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;?  Make a list, and then prioritize it by importance and expected effort.&lt;/p&gt;
&lt;h4 id=&#34;3-take-things-one-at-a-time&#34;&gt;3. Take things one at a time&lt;/h4&gt;
&lt;p&gt;Once you have a list of things that you want to fix, it can be tempting to try to fit those fixes in all over the places.  You&amp;rsquo;re creating a new page, might as well write it in Vue instead of Angular.  You&amp;rsquo;re changing some styles, maybe you can use a CSS in JS library.  But the absolute worst thing you can do with limited resources is try to improve too many things at once.  You&amp;rsquo;ll end up with a codebase with many different ways to do everything, so that every change requires a full context reset, and maintenance means dealing with multiple sets of bugs and compatibility issues for each duplicated approach.  That&amp;rsquo;s why prioritization is critical.  With limited bandwidth, you need to know what &lt;strong&gt;one thing&lt;/strong&gt; will be the best use of your time.&lt;/p&gt;
&lt;h4 id=&#34;4-expand-from-small-footholds-dont-boil-the-ocean&#34;&gt;4. Expand from small footholds, don&amp;rsquo;t boil the ocean&lt;/h4&gt;
&lt;p&gt;A few truths to note at this point:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Changing large systems is hard.&lt;/strong&gt;  They have a million different subtle assumptions weaved into their code, and making seemingly the same change in different places can often produce subtly different results.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Practice is how you learn to use a tool or technique optimally.&lt;/strong&gt; Unless you&amp;rsquo;ve already used a technology extensively in a different context, you will never be more blind to it&amp;rsquo;s downsides than at the start of adding it to a project.  As you begin using it, you&amp;rsquo;ll learn more about it and how to use it better in your system.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Well designed systems have good interface points&lt;/strong&gt;.  Interface points are areas where one part of the system doesn&amp;rsquo;t need to care about the details of how other parts of the system are implemented, they just need to know the &lt;em&gt;interface&lt;/em&gt; for interacting with that part of the system.  For example, when using React, parent components don&amp;rsquo;t need to know the details of how a child component work, just what props they take.  Similarly when writing HTMl, you don&amp;rsquo;t need to know the details of how CSS will work for layout, you just need to expose meaningful class names that CSS can use.  A website doesn&amp;rsquo;t need to know what language a web server is written in to make HTML requests to it.  These are examples of interface points, and while well designed systems will have more of them and fewer &amp;ldquo;breaches&amp;rdquo; of the interface lines, all systems have them to some extent.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The implication of these truths is that there is value in starting small and expanding.  If we can pick a small section of the application that is cordoned off from the rest of the code in a meaningful way, we can create a foothold for the new technology.  This serves as a learning opportunity, an example, and a starting place.  If it goes badly, small changes are easy to revert or fix.  If it works well, we can look for more similar interface boundaries, or expand out to convert some of the code that uses the new code.&lt;/p&gt;
&lt;p&gt;When I converted a large Backbone app to use React, I took advantage of 2 different interface boundaries.  I started by converting small &amp;ldquo;widget&amp;rdquo; components to be written in React, and came up with a method of calling these widgets from within Backbone code.  Once I had enough of these building block widgets written in React, I started writing new pages in React.  Then finally I would convert subsections of Backbone driven pages to React, starting from the bottom up and converting the top level layouts of the page last.  I was using 2 interface boundaries: components and pages.  That made sense for Backbone to React, where I was essentially converting one type of component tree to another.  But the lines may be different for other changes, and you&amp;rsquo;ll need to use your judgement.&lt;/p&gt;
&lt;h4 id=&#34;5-automate-what-you-can&#34;&gt;5. Automate what you can&lt;/h4&gt;
&lt;p&gt;Not every change needs to be hard and slow.  Sometimes we can take advantage of automation. Tools like &lt;a href=&#34;https://prettier.io/&#34;&gt;Prettier&lt;/a&gt; and &lt;a href=&#34;https://eslint.org/&#34;&gt;ESLint&lt;/a&gt; make it easy to automate code style and correctness fixes.  Tools like React often provide &lt;a href=&#34;https://github.com/reactjs/react-codemod&#34;&gt;codemods&lt;/a&gt; to help make it easier to update to a new version of the tool or use best practices.  Unit tests can help you prevent regression bugs and are easy to automate with a CI server or &lt;a href=&#34;https://benmccormick.org/2017/02/26/running-jest-tests-before-each-git-commit/&#34;&gt;pre-commit hooks&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re dealing with problems that are more specific to your codebase, it may make sense to invest time into writing your own automation scripts, whether that means hacking together a crazy bash/python script to do a massive find and replace, or using a tool like Ansible to automate some previously manual developer processes. It made a big difference in our company when our QA developer put in the work to automate the creation of consistent local environments.&lt;/p&gt;
&lt;h4 id=&#34;6-count-the-cost-of-maintenance&#34;&gt;6. Count the cost of maintenance&lt;/h4&gt;
&lt;p&gt;With a small team, some improvements may simply not be worth it over time.  Genuinely valuable things like test coverage, JSDoc style automated documentation, old browser support, add overhead to future changes as well as any up front cost to implement. These are the type of things that advocates tend to moralize about, and say that it&amp;rsquo;s the developers job to advocate for them.  And that is true as I alluded to earlier.  But when faced with limited resources, it&amp;rsquo;s important to prioritize, and understanding the cost of maintaining certain improvements is part of that.&lt;/p&gt;
&lt;h4 id=&#34;7-distinguish-between-craftsmanship-and-business-needs&#34;&gt;7. Distinguish between craftsmanship and business needs&lt;/h4&gt;
&lt;p&gt;Along the same lines, as developers we&amp;rsquo;re often encouraged to think of ourselves as craftsmen.  Think of &lt;a href=&#34;https://thenextweb.com/apple/2011/10/24/steve-jobs-obsession-with-the-quality-of-the-things-unseen/&#34;&gt;Steve Jobs talking about using good wood for the back of a cabinet&lt;/a&gt; or the aforementioned moralizing about code and process quality.  There are great things about this, since it is a developers job to look after the quality and craftsmanship of their product.  But it also is good to align that craftsmanship with business needs and create something that is useful rather than merely theoretically beautiful.  So there is a place for making changes to improve the &amp;ldquo;purity&amp;rdquo; of code, but when investing limited resources, it&amp;rsquo;s even more important than usual to balance that with business needs.&lt;/p&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;I&amp;rsquo;ve gotten to work with plenty of non-devs who respect the need for good architecture.  They still aren&amp;rsquo;t going to be able to identify when changes need to happen.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;Little known fact: CSS actually stands for &amp;ldquo;Giant Tangled Mess that creates bugs with every change&amp;rdquo;&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>Weekly Links: January 5th</title>
      <link>https://benmccormick.org/2018/01/04/weekly-links-january.html</link>
      <pubDate>Thu, 04 Jan 2018 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2018/01/05/weekly-links-january.html</guid>
      <description>&lt;h3 id=&#34;working-in-the-tech-industry&#34;&gt;Working in The Tech Industry&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.codinghorror.com/to-serve-man-with-software/&#34;&gt;To Serve Man With Software | Jeff Atwood&lt;/a&gt; - This is a great review of the ethical questions that software developer&amp;rsquo;s face in the modern world.  Is your work actually serving anyone who isn&amp;rsquo;t invested in your employer?&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://m.signalvnoise.com/basecamp-doesnt-employ-anyone-in-san-francisco-but-now-we-pay-everyone-as-though-all-did-3ee87013cfc2&#34;&gt;Basecamp doesn’t employ anyone in San Francisco, but now we pay everyone as though all did | Basecamp&lt;/a&gt; - On a similar vein, this is a tech employer holding themselves to a higher standard in terms of benefiting their employees&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.  Also this quote is a fantastic summary of the type of software companies I want to work for:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Especially in software, which is a profitable business when run with restraint and sold to businesses.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;There&amp;rsquo;s a glorification of the unicorn startup in the tech world, but you can go a long way with low costs and high paying customers (and it&amp;rsquo;s easier to &amp;ldquo;serve man with software&amp;rdquo; without outside pressure to grow like crazy)&lt;/p&gt;
&lt;h3 id=&#34;non-tech-less-tech&#34;&gt;Non-Tech (&amp;ldquo;Less-Tech&amp;rdquo;?)&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/zonination/perceptions&#34;&gt;Perceptions of Probability and Numbers | Zoni Nation&lt;/a&gt; -  This is simply a collection of visualizations of a dataset pulled from Reddit of what probabilities people associate with common english phrases used to express uncertainty.  I found it fascinating.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/prob-graph.png&#34; alt=&#34;An example graph from the repo&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://mashable.com/2017/12/27/browser-bar-url-facebook-bad/&#34;&gt;Stop Using Facebook and Start Using Your Browser | Foster Kamer&lt;/a&gt; - This is a call for people to get out of their social media bubble and &lt;em&gt;internet like it&amp;rsquo;s 2005&lt;/em&gt;.  Use bookmarks, type in URLs directly, basically go to sites directly for content instead of relying on social media algorithms to find stuff for you.  I think this is easier said than done.  Social networking sites are ingrained into our culture at this point. You don&amp;rsquo;t replace culture by condemning it, and telling everyone to go without but by creating something new or better&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;.  So what can we make as Internet users that provides something as easy or easier than the mindless serendipity of social media, but produces better outcomes?&lt;/p&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;Feel free to be cynical about this as a marketing ploy, but I&amp;rsquo;m all for companies marketing themselves by actually improving how they compensate their employees.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;If you&amp;rsquo;d like to read a whole book making that argument, I recommend &lt;a href=&#34;http://amzn.to/2F9xdD6&#34;&gt; Culture Making by Andy Crouch&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>2017 Roundup</title>
      <link>https://benmccormick.org/2017/12/29/190000.html</link>
      <pubDate>Fri, 29 Dec 2017 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2017/12/30/190000.html</guid>
      <description>&lt;p&gt;2017 was the 5th full year of this blog, and in many ways it was the most productive. I wrote one of the most popular things I’ve written on here, started the weekly links section (on hiatus for New Years, but will return next week), and wrote 21 full articles and 8 weekly links post, the most I’ve ever posted here in a year. Here are some of the highlights from my blog and development this year.&lt;/p&gt;
&lt;h3 id=&#34;mostreadpostspublishedin2017&#34;&gt;Most Read Posts Published in 2017&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://benmccormick.org/2017/07/19/ten-things-javascript/&#34;&gt;Ten Things A Serious JavaScript Developer Should Learn&lt;/a&gt; - It turns out that making lists of things is a good way to get traffic. I wonder if anybody else on the internet has figured this out?&lt;/p&gt;
&lt;figure&gt;
&lt;figcaption&gt;&lt;img style=&#34;display: block; margin-left: auto; margin-right: auto;&#34; title=&#34;list_analytics.png&#34; src=&#34;https://benmccormick.micro.blog/uploads/2022/a08ee486c3.png&#34; alt=&#34;List analytics&#34; width=&#34;599&#34; height=&#34;109&#34; border=&#34;0&#34; /&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;In all seriousness, I think there’s a hunger out there for clearer roadmaps for folks who are early out in their front end development career. People are telling them to learn all the frameworks, all the tools and all the compile-to-JS languages, and everyone knows they can’t learn it all. So even an imperfect list that can serve as a starting point for figuring that out can get some traction. This article was my attempt to answer “what should a serious mid-level JavaScript developer have learned and be learning?”.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://benmccormick.org/2017/07/10/how-to-follow-the-javascript-roadmap/&#34;&gt;How To Follow The JavaScript Roadmap&lt;/a&gt; - This post was aimed at a similar audience to the “Serious JavaScript Developer” post, but aimed to help folks who want to follow changes in the JavaScript language keep up with new developments.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://benmccormick.org/2017/01/03/orthogonality-and-css-in-js/&#34;&gt;Orthogonality and CSS in JS&lt;/a&gt; - This article was an examination of the architecture tradeoffs of CSS in JS solutions, and also an examination of how people discuss “separations of concerns” in general. If you liked this one, keep your eyes open. I’m planning on writing more architecture level posts in 2018.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;codeiwrotein2017&#34;&gt;Code I wrote in 2017&lt;/h3&gt;
&lt;p&gt;Most of the code I wrote this year was again for my work at Windsor Circle. But I’ve continued to add new features to this blog, which is based on React and Gatsby, and the source code for that is available &lt;a href=&#34;https://github.com/benmccormick/benmccormickorg&#34;&gt;on Github&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;talksigavein2017&#34;&gt;Talks I gave in 2017&lt;/h3&gt;
&lt;p&gt;This was a big speaking year for me. I gave 3 different talks: &lt;a href=&#34;https://www.slideshare.net/BenMcCormick/vim-survival-guide-71763917&#34;&gt;The Vim Survival Guide&lt;/a&gt; at Open Source 101, &lt;a href=&#34;https://www.slideshare.net/BenMcCormick/gatsby-intro&#34;&gt;Intro to Gatsby&lt;/a&gt; at a local meetup group and &lt;a href=&#34;https://www.slideshare.net/BenMcCormick/saving-time-by-testing-with-jest&#34;&gt;Saving Time with Jest&lt;/a&gt; at All Things Open. I’d be interested in giving any of those talks again next year, so if you’re looking for a speaker, feel free to reach out.&lt;/p&gt;
&lt;h3 id=&#34;languageslibrariesandtechnologiesistartedusingin2017&#34;&gt;Languages, Libraries, and Technologies I started using in 2017&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://mobx.js.org/&#34;&gt;Mobx&lt;/a&gt; is a JavaScript data modeling library that serves as an alternative to Redux or React state for state management. I wrote about my &lt;a href=&#34;https://benmccormick.org/2017/01/09/mobx-first-impressions/&#34;&gt;first impressions&lt;/a&gt; at the beginning of the year, but I’ve continued to use it and love it since then.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://yarnpkg.com/en/&#34;&gt;Yarn&lt;/a&gt; was a nice upgrade over npm. My understanding is that npm has since stepped up and closed the gap here, but I’m continuing to use Yarn for now since it has taken over my projects and muscle memory.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;When I upgraded this blog to Gatsby 1.0, I had the opportunity to learn about &lt;a href=&#34;http://graphql.org/&#34;&gt;GraphQL&lt;/a&gt;. I’ve really enjoyed getting to play with it and love the GraphQL community’s dedication to providing a great developer experience.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;languagesandlibrariesiusedmoreorlesseverydayin2017&#34;&gt;Languages and Libraries I used (more or less) every day in 2017&lt;/h3&gt;
&lt;p&gt;JavaScript (ES6), Python, React, PostgreSQL, Backbone (&lt;strong&gt;sigh&lt;/strong&gt;), lodash, MobX, Jest&lt;/p&gt;
&lt;h3 id=&#34;languagesandlibrariesiwanttotryin2018&#34;&gt;Languages and Libraries I want to try in 2018&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/FormidableLabs/victory&#34;&gt;Victory&lt;/a&gt;, Rust, and Pandas/other python data analysis libraries &lt;a id=&#34;fnref:1&#34; class=&#34;footnote&#34; title=&#34;see footnote&#34; href=&#34;#fn:1&#34;&gt;[1]&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;blogsistartedfollowingin2017&#34;&gt;Blogs I started following in 2017&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;http://blog.isquaredsoftware.com/&#34;&gt;Mark Erikson’s Dev blog&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;blogsireadeverypostfromin2017&#34;&gt;Blogs I read every post from in 2017&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;http://randsinrepose.com/&#34;&gt;Rands In Repose&lt;/a&gt;, &lt;a href=&#34;https://stratechery.com/&#34;&gt;Stratechery&lt;/a&gt;, &lt;a href=&#34;https://daringfireball.net/&#34;&gt;Daring Fireball&lt;/a&gt;, &lt;a href=&#34;http://purposedworking.org/&#34;&gt;purposedworking.org&lt;/a&gt;, &lt;a href=&#34;https://wynnnetherland.com/&#34;&gt;wynnnetherland.com&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;podcastsistartedlisteningtoin2017&#34;&gt;Podcasts I started listening to in 2017&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://www.npr.org/sections/money/&#34;&gt;Planet Money&lt;/a&gt; - A long running NPR podcast about money, the economy, and the unexpected ways they affect our everyday lives&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://www.theallusionist.org/&#34;&gt;The Allusionist&lt;/a&gt; - A great podcast on the crazy history behind different words in the English language.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;softwareistartedusingin2017&#34;&gt;Software I started using in 2017&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://www.bear-writer.com/&#34;&gt;Bear&lt;/a&gt; - I mentioned I was testing this out at the end of last year, but it has become my go-to notes application, and I would recommend it to anyone who wants a stylish notes app in the middle ground between Apple Notes and Evernote (and who uses Apple products).&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;softwareiusednearlyeverydayin2017&#34;&gt;Software I used (nearly) every day in 2017&lt;/h3&gt;
&lt;p&gt;MacOS/iOS, Google Search, Chrome/Safari/Firefox, GMail/MailPlane 3, Twitter/Tweetbot, Feedbin/Reeder, Instapaper, iMessage, Slack, Trello, 1Password, Atom/Vim, iTerm, Fish Shell, Bitbucket, Fantastical, Spotify, Bear, Annotate, Dash&lt;/p&gt;
&lt;div class=&#34;footnotes&#34;&gt;&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;Yes this is basically the same list as last year. ¯\_(ツ)_/¯ I mostly learn tech as I have need for it, and it was a very “nose to the grindstone” year focused on improving existing codebases this year &lt;a class=&#34;reversefootnote&#34; title=&#34;return to article&#34; href=&#34;#fnref:1&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Weekly Links: December 23rd 2017</title>
      <link>https://benmccormick.org/2017/12/22/weekly-links-december.html</link>
      <pubDate>Fri, 22 Dec 2017 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2017/12/23/weekly-links-december.html</guid>
      <description>&lt;h3 id=&#34;javascript-and-the-web&#34;&gt;JavaScript And The Web&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;http://raganwald.com/2017/12/14/73939133.html&#34;&gt;73,939,133 / Truncatable Primes | Reg Braithwaite&lt;/a&gt; - A nice writeup about how brute force can be useful in solving a &lt;a href=&#34;https://projecteuler.net/&#34;&gt;Project Euler&lt;/a&gt; style math problem.&lt;/p&gt;
&lt;h3 id=&#34;programming-tools-and-practices&#34;&gt;Programming Tools and Practices&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;http://facebook.github.io/jest/blog/2017/12/18/jest-22.html&#34;&gt;Jest 22: Refinements &amp;amp; Custom Runners | Jest Blog&lt;/a&gt; - This looks like a solid refinement release for Jest.  One warning: If you&amp;rsquo;re running &lt;code&gt;jest -o&lt;/code&gt; on precommit hooks as I described &lt;a href=&#34;https://benmccormick.org/2017/02/26/running-jest-tests-before-each-git-commit/&#34;&gt;here&lt;/a&gt;, Jest 22 fails when run with 0 tests, so you need to specify the &lt;code&gt;--passWithNoTests&lt;/code&gt; flag in order to let things go when you make a change that doesn&amp;rsquo;t affect any tests.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.gatsbyjs.org/blog/2017-12-20-introducing-the-gatsby-ux-research-program/&#34;&gt;Introducing The Gatsby UX Research Program | Gatsby Blog&lt;/a&gt; - An unusual case of doing real UX research for an open source developer tool.  Very cool stuff.&lt;/p&gt;
&lt;h3 id=&#34;non-tech&#34;&gt;Non-Tech&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://www.justinobeirne.com/google-maps-moat&#34;&gt;Google Maps’s Moat&lt;/a&gt; - If you have any interest in product design, maps, or computer intelligence, this is the one article you need to read this week.  Beautifully put together.  It&amp;rsquo;s an in depth examination of the difference between Google and Apple maps, but it reads as a deeper exploration of how big data combined with computer learning and automation can have a huge impact on product design.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://izbicki.me/blog/how-to-cheat-at-settlers-of-catan-by-loading-the-dice-and-prove-it-with-p-values.html&#34;&gt;How to cheat at settlers by loading the dice | Mike Izbicki&lt;/a&gt; - This is just a fun application of statistics to my favorite board game.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Weekly Links: December 15th 2017</title>
      <link>https://benmccormick.org/2017/12/14/weekly-links-december.html</link>
      <pubDate>Thu, 14 Dec 2017 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2017/12/15/weekly-links-december.html</guid>
      <description>&lt;h3 id=&#34;javascript-and-the-web&#34;&gt;JavaScript And The Web&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://stateofjs.com/&#34;&gt;The State Of JavaScript 2017&lt;/a&gt; - This annual survey of JavaScript developers always has lots of interesting insights.  Since it is an internet survey, I view it less as a full snapshot of the industry, but more as a place to see what is new and trending in the JS world.  This year &lt;a href=&#34;https://code.visualstudio.com/&#34;&gt;Visual Studio Code&lt;/a&gt;, &lt;a href=&#34;https://prettier.io/&#34;&gt;Prettier&lt;/a&gt; and &lt;a href=&#34;https://vuejs.org/&#34;&gt;Vue&lt;/a&gt; caught my eye as spiking in popularity.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://engineering.linkedin.com/blog/2017/12/the-glimmer-binary-experience&#34;&gt;The Glimmer Binary Experience | LinkedIn Engineering&lt;/a&gt; - I had the privilege of seeing Yehuda Katz, one of the Ember core developers, give a talk about &lt;a href=&#34;https://glimmerjs.com/&#34;&gt;Glimmer&lt;/a&gt; and bytecode at this year&amp;rsquo;s All Things Open conference.  They&amp;rsquo;re doing some pretty serious software engineering in the Ember community right now.  This write-up covers a lot of the same ground and is worth a read.&lt;/p&gt;
&lt;h3 id=&#34;programming-tools-and-practices&#34;&gt;Programming Tools and Practices&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;http://blog.atom.io/2017/12/12/atom-1-23.html&#34;&gt;Atom 1.23&lt;/a&gt; and &lt;a href=&#34;https://code.visualstudio.com/updates/v1_19&#34;&gt;Visual Studio Code 1.19&lt;/a&gt; were released this week, making this a big week for Electron based text editors.  If you use either of them, you&amp;rsquo;ll get to enjoy a nice set of performance improvements when you upgrade.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.bear-writer.com/bear-1-4-the-tags-edition-298d6fdc55dd&#34;&gt;Bear 1.4&lt;/a&gt; - Speaking of software that I love to use getting updates, I&amp;rsquo;ve been using Bear as my primary notes app for the last year, and it is a delight.  Getting autocomplete on tags this week solved it&amp;rsquo;s last real annoyance for me, and I would definitely recommend it to anyone interested in a simple notes app.  It&amp;rsquo;s more powerful than Apple&amp;rsquo;s notes or text files, but cleaner and more elegant than &lt;a href=&#34;https://evernote.com/&#34;&gt;Evernote&lt;/a&gt;.  And even the paid level is very affordable.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Weekly Links: December 8th 2017</title>
      <link>https://benmccormick.org/2017/12/07/weekly-links-december.html</link>
      <pubDate>Thu, 07 Dec 2017 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2017/12/08/weekly-links-december.html</guid>
      <description>&lt;h3 id=&#34;javascript-and-the-web&#34;&gt;JavaScript And The Web&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://reactjs.org/blog/2017/12/07/introducing-the-react-rfc-process.html&#34;&gt;Introducing the React RFC Process | React Blog&lt;/a&gt; - React is now using a public process for proposing and designing new features, starting with a new context API.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.neufund.org/why-we-have-banned-default-exports-and-you-should-do-the-same-d51fdc2cf2ad&#34;&gt;Why we have banned default exports in Javascript and you should do the same | Krzysztof Kaczor&lt;/a&gt; - This lines up pretty well with my own experience when it comes to native JS modules.  The named exports are pretty much always better than the default ones.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://egghead.io/courses/advanced-react-component-patterns&#34;&gt;Advanced React Component Patterns | Egghead.io/Kent C. Dobbs&lt;/a&gt; - This is a new Egghead course on React Component patterns, and is the best &amp;ldquo;advanced&amp;rdquo; React resource I&amp;rsquo;ve seen.  If you&amp;rsquo;re a React developer, you should either watch it this weekend while it is still free, or pay up to Egghead (it will be behind their subscriber wall starting Monday).  He also released a &lt;a href=&#34;https://egghead.io/courses/the-beginner-s-guide-to-reactjs&#34;&gt;beginner level React course&lt;/a&gt; this week that will remain free.&lt;/p&gt;
&lt;h3 id=&#34;non-tech&#34;&gt;Non-Tech&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://stratechery.com/2017/the-pollyannish-assumption/&#34;&gt;The Pollyannish Assumption | Stratechery&lt;/a&gt; - Ben Thompson gives a pretty good breakdown here of the problems companies face moderating Internet scale content.  Human beings capable of both greater heights and darker depths than we like to think.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Weekly Links: December 1st 2017</title>
      <link>https://benmccormick.org/2017/11/30/weekly-links-december.html</link>
      <pubDate>Thu, 30 Nov 2017 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2017/12/01/weekly-links-december.html</guid>
      <description>&lt;h3 id=&#34;javascript-and-the-web&#34;&gt;JavaScript And The Web&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;http://2ality.com/2017/04/flatmap.html&#34;&gt;Functional pattern: flatMap | 2ality&lt;/a&gt; - This post isn&amp;rsquo;t new, but &lt;code&gt;flatmap&lt;/code&gt; and &lt;code&gt;flatten&lt;/code&gt; hit stage 3 in the TC39 process for adding new features to JavaScript this week&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.  So this is a great time to read up on them.&lt;/p&gt;
&lt;blockquote class=&#34;twitter-tweet&#34; data-lang=&#34;en&#34;&gt;&lt;p lang=&#34;en&#34; dir=&#34;ltr&#34;&gt;Stage 3 for Array.prototype.flatMap and Array.prototype.flatten! Thank you so much &lt;a href=&#34;https://twitter.com/jspedant?ref_src=twsrc%5Etfw&#34;&gt;@jspedant&lt;/a&gt; for driving this!&lt;a href=&#34;https://t.co/9kLCKJcZEv&#34;&gt;https://t.co/9kLCKJcZEv&lt;/a&gt;&lt;/p&gt;&amp;mdash; Brian Terlson (@bterlson) &lt;a href=&#34;https://twitter.com/bterlson/status/935582351999901696?ref_src=twsrc%5Etfw&#34;&gt;November 28, 2017&lt;/a&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&#34;http://bholley.net/blog/2017/stylo.html&#34;&gt;Boiling the Ocean, Incrementally - How Stylo Brought Rust and Servo to Firefox | Bobby Holley &lt;/a&gt; - This is a great review of the technical achievement that Firefox 57 represents, and also gives some insight into where Mozilla is going from here. I&amp;rsquo;ve switched back to Firefox over the past 2 weeks and am pretty happy with it so far.&lt;/p&gt;
&lt;h3 id=&#34;programming-tools-and-practices&#34;&gt;Programming Tools and Practices&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://aws.amazon.com/blogs/aws/introducing-amazon-appsync/&#34;&gt;Introducing AWS AppSync | AWS News Blog&lt;/a&gt; - AWS announced a bunch of new services this week, but I wanted to highlight AppSync, an Amazon GraphQL service.  &lt;a href=&#34;http://graphql.org/&#34;&gt;GraphQL&lt;/a&gt; seems to be gaining more and more momentum, and if you don&amp;rsquo;t know anything about it I&amp;rsquo;d suggest checking it out.  I&amp;rsquo;ve gotten to play with it since rewriting my blog to &lt;a href=&#34;https://www.gatsbyjs.org/&#34;&gt;Gatsby&lt;/a&gt; 1.0, and it is a nice way to work with data.&lt;/p&gt;
&lt;h3 id=&#34;non-tech&#34;&gt;Non-Tech&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://www.seattletimes.com/business/amazon/this-city-hall-brought-to-you-by-amazon/&#34;&gt;This City Hall, brought to you by Amazon | The Seattle Times&lt;/a&gt; - I&amp;rsquo;m amazed by the incentives cities have been willing to offer Amazon to locate a headquarters in their city.  I think the outrage in this column is a bit over the top, but it is a startling insight into the power large tech companies have over the cities where they&amp;rsquo;re located.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://amzn.to/2i78Knm&#34;&gt;Doomsday Clock - #1&lt;/a&gt; - If you have any interest in comic books DC&amp;rsquo;s &lt;a href=&#34;http://amzn.to/2i78Knm&#34;&gt;Watchmen&lt;/a&gt; sequel has begun.  It&amp;rsquo;s a story that crosses over with the mainstream DC Universe, and appears to be a rebuttal of the cynical vantage point of the original work.  This is the first of 12 issues over the next year and it was a strong (but slow start).  If you&amp;rsquo;re interested in Watchmen but don&amp;rsquo;t read a lot of comics, this is the continuation of a story that began with &lt;a href=&#34;http://amzn.to/2jD0Y5c&#34;&gt;a big DC special&lt;/a&gt; and continued in a special &lt;a href=&#34;http://amzn.to/2i5zSDn&#34;&gt;Batman/Flash crossover&lt;/a&gt;&lt;/p&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;See &lt;a href=&#34;https://benmccormick.org/2017/07/10/how-to-follow-the-javascript-roadmap/&#34;&gt;this post&lt;/a&gt; for more info about staying informed about features that are being added to JavaScript.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>Implementing The Sieve Of Eratosthenes in JavaScript</title>
      <link>https://benmccormick.org/2017/11/27/190000.html</link>
      <pubDate>Mon, 27 Nov 2017 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2017/11/28/190000.html</guid>
      <description>&lt;p&gt;As a way of keeping my math skills sharp, I’ve recently started to work through the &lt;a href=&#34;https://projecteuler.net/&#34;&gt;Project Euler&lt;/a&gt; set of computational math problems. They ask you not to post your work publicly, so I won’t be posting about any of my specific solutions, but I did think it would be fun to share about a helper method I’ve been using.&lt;/p&gt;
&lt;p&gt;For several of the Project Euler problems I’ve worked on, I needed to be able to generate a list of prime numbers. To do that, I borrowed a Python implementation of the Sieve Of Erathosthenes from &lt;a href=&#34;https://stackoverflow.com/a/568618/1424361&#34;&gt;this StackOverflow answer&lt;/a&gt;. Since I haven’t had much reason to use generators in JavaScript yet, I thought it would be fun to translate that algorithm to JavaScript and share that here.&lt;/p&gt;
&lt;h3 id=&#34;sieveoferatosthenes&#34;&gt;Sieve of Eratosthenes&lt;/h3&gt;
&lt;p&gt;The Sieve of Erathosthenes is a very old&lt;a id=&#34;fnref:1&#34; class=&#34;footnote&#34; title=&#34;see footnote&#34; href=&#34;#fn:1&#34;&gt;[1]&lt;/a&gt; simple algorithm for identifying prime numbers. In its normal implementation it is a useful way of finding small primes up to a certain number. Beginning at 2, the algorithm iterates upward. For the current number, if the number has not been marked, we identify it as a prime, and then mark all multiples of that number up to our target number. So to find all primes up to 12, we would&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;start at 2, note &lt;strong&gt;2&lt;/strong&gt; as prime, and mark 4, 6, 8, 10 and 12 as non-prime&lt;/li&gt;
&lt;li&gt;move to 3, note &lt;strong&gt;3&lt;/strong&gt; as prime, and mark 6, 9, 12 as non-prime&lt;/li&gt;
&lt;li&gt;move to 4, see that it is marked, and skip it&lt;/li&gt;
&lt;li&gt;move to 5, note &lt;strong&gt;5&lt;/strong&gt; as prime and mark 10 as non-prime&lt;/li&gt;
&lt;li&gt;move to 6, see that it is marked and skip it&lt;/li&gt;
&lt;li&gt;move to 7 , note &lt;strong&gt;7&lt;/strong&gt; as prime&lt;/li&gt;
&lt;li&gt;see that 8–10 are marked and skip them&lt;/li&gt;
&lt;li&gt;move to 11, note &lt;strong&gt;11&lt;/strong&gt; as prime&lt;/li&gt;
&lt;li&gt;move to 12, see that it is marked and skip it&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can see it graphically with this visualization from &lt;a href=&#34;https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes&#34;&gt;Wikipedia&lt;/a&gt;:&lt;/p&gt;
&lt;figure&gt;&lt;br /&gt;
&lt;figcaption&gt;&lt;br /&gt;&lt;img style=&#34;display: block; margin-left: auto; margin-right: auto;&#34; title=&#34;sieve-animation.gif&#34; src=&#34;https://benmccormick.micro.blog/uploads/2022/5f36ffb53b.gif&#34; alt=&#34;sieve animation, shows the numbers being marked visually&#34; width=&#34;445&#34; height=&#34;369&#34; border=&#34;0&#34; /&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h3 id=&#34;pythonimplementation&#34;&gt;Python Implementation&lt;/h3&gt;
&lt;p&gt;The Python implementation that I used makes some modifications to the classic version of the algorithm that lets it generate an indefinite number of primes while being memory efficient&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;python&#34;&gt;def gen_primes():
    &#34;&#34;&#34; Generate an infinite sequence of prime numbers.&#34;&#34;&#34;
    marked_not_prime = {}
    value_to_check = 2
    while True:
        if value_to_check not in marked_not_prime:
            yield value_to_check
            marked_not_prime[value_to_check * value_to_check] = [value_to_check]
        else:
            for prime in marked_not_prime[value_to_check]:
                marked_not_prime.setdefault(prime + value_to_check, []).append(prime)
            del marked_not_prime[value_to_check]
        value_to_check += 1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This version of the algorithm keeps a running set of the relevant matches, and keeps only the ones it needs. We can translate it more or less directly to JavaScript like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;javascript&#34;&gt;function* generatePrimes() {
    const markedNotPrime = {};
    let valueToCheck = 2;
    while(true) {
        if (!(valueToCheck in markedNotPrime)) {
            yield valueToCheck
            markedNotPrime[valueToCheck**2] = [valueToCheck]
        } else {
            let primes =markedNotPrime[valueToCheck];
            primes.forEach(prime=&amp;gt; {
                let nextMultipleOfPrime = prime + valueToCheck;
                if (nextMultipleOfPrime in markedNotPrime) {
                    markedNotPrime[nextMultipleOfPrime].push(prime);
                } else {
                    markedNotPrime[nextMultipleOfPrime] = [prime];
                }
            })
            delete markedNotPrime[valueToCheck];
        }
        valueToCheck += 1
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let’s break down what this is doing.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;javascript&#34;&gt;function* generatePrimes() {
  //...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;generatePrimes&lt;/code&gt; is a JavaScript &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator&#34;&gt;generator&lt;/a&gt;. Generators “generate” a series of values in a “just in time” fashion; they only calculate the next value when it is needed, making them an efficient solution for working with large or infinite series. You specify a generator function by adding the &lt;code&gt;*&lt;/code&gt; to the function declaration. Generators then use the &lt;code&gt;yield&lt;/code&gt; keyword rather than &lt;code&gt;return&lt;/code&gt; to return their values, and can &lt;code&gt;yield&lt;/code&gt; multiple times. After a generator yields, it pauses execution until it is asked for another value. For our &lt;code&gt;generatePrimes&lt;/code&gt; function, we are operating inside an infinite loop and will yield continuously without stopping&lt;a id=&#34;fnref:2&#34; class=&#34;footnote&#34; title=&#34;see footnote&#34; href=&#34;#fn:2&#34;&gt;[2]&lt;/a&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;javascript&#34;&gt;const markedNotPrime = {};
let valueToCheck = 2;
while(true) {
    //...
    valueToCheck += 1
}
&lt;p&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;We’re using a plain object to keep track of our marked numbers, and using &lt;code&gt;valueToCheck&lt;/code&gt; to keep track of where we are in iterating through numbers. As noted, we will iterate it forever if the generator continues to be called.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;javascript&#34;&gt;if (!(valueToCheck in markedNotPrime)) {
    yield valueToCheck
    markedNotPrime[valueToCheck**2] = [valueToCheck]
} else {
  //...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As in the original algorithm, if we get to a number that isn’t marked, we know that it is a prime. So we &lt;code&gt;yield&lt;/code&gt; it, which pauses execution. If the generator is queried again, when we resume execution we mark the prime squared as not-prime, and we do that by assigning it an array with the current prime value in it. Using arrays for markers will make more sense in a moment. For now its worth noting that we only need to mark prime-squared as non-prime since every multiple below that is the current prime multiplied by a number less than it, which means it will already be covered, as we will see below.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;javascript&#34;&gt;if (!(valueToCheck in markedNotPrime)) {
  //...
} else {
    let primes = markedNotPrime[valueToCheck];
    primes.forEach(prime =&amp;gt; {
        let nextMultipleOfPrime = prime + valueToCheck;
        if (nextMultipleOfPrime in markedNotPrime) {
            markedNotPrime[nextMultipleOfPrime].push(prime);
        } else {
            markedNotPrime[nextMultipleOfPrime] = [prime];
        }
    })
    delete markedNotPrime[valueToCheck];
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here’s the clever part of this implementation. When we hit a number that is marked as not-prime, instead of just skipping it and moving on, we use some logic to keep our list of marked values small and memory efficient. This is also what allows us to get an infinite list of primes instead of settling for those under a particular value. What we want to do is keep a list of all the primes that are factors of each marked number. Then when we hit a number that is marked, we mark the next multiple for each prime (&lt;code&gt;valueToCheck + prime&lt;/code&gt;), and remove the current value from the object. That keeps checks fairly cheap by eliminating the number of marked numbers, and allows us to only add values to the marked list as we need them.&lt;/p&gt;
&lt;p&gt;We can then use this code to get the 1,000,001st prime like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;javascript&#34;&gt;let gen = generatePrimes();
for(var i=0; i&amp;lt; 1000000; i ++) {
    gen.next()
}
console.log(gen.next().value)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That executed on my laptop in ~20seconds, approximately the same as the python implementation in python2, a little slower than running it under python3. I was curious whether using a &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map&#34;&gt;Map&lt;/a&gt; for our marked prime list would speed things up:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;javascript&#34;&gt;function* generatePrimes() {
    const markedNotPrimeMap = new Map();
    let valueToCheck = 2;
    while(true) {
        if (!(markedNotPrimeMap.has(valueToCheck))) {
            yield valueToCheck
            markedNotPrimeMap.set(valueToCheck**2, [valueToCheck])
        } else {
            let primes =markedNotPrimeMap.get(valueToCheck)
            primes.forEach(prime=&amp;gt; {
                let nextMultipleOfPrime = prime + valueToCheck;
                if (markedNotPrimeMap.has(nextMultipleOfPrime)) {
                    markedNotPrimeMap.get(nextMultipleOfPrime).push(prime);
                } else {
                    markedNotPrimeMap.set(nextMultipleOfPrime, [prime]);
                }
            })
            markedNotPrimeMap.delete(valueToCheck);
        }
        valueToCheck += 1
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This version of the code runs about 25% faster, in 15 seconds on my machine. Not bad.&lt;/p&gt;
&lt;h3 id=&#34;moreresources&#34;&gt;More Resources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;You can dig in more on the Sieve of Erosthenes on &lt;a href=&#34;https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes&#34;&gt;Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Check out &lt;a href=&#34;https://projecteuler.net/&#34;&gt;Project Euler&lt;/a&gt; for some fun computational math problems.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;footnotes&#34;&gt;&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;There are references as old as ~100 AD &lt;a class=&#34;reversefootnote&#34; title=&#34;return to article&#34; href=&#34;#fnref:1&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;At least until we hit system boundaries for memory/number size/etc. &lt;a class=&#34;reversefootnote&#34; title=&#34;return to article&#34; href=&#34;#fnref:2&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Weekly Links: Thanksgiving 2017 edition</title>
      <link>https://benmccormick.org/2017/11/25/weekly-links-thanksgiving.html</link>
      <pubDate>Sat, 25 Nov 2017 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2017/11/26/weekly-links-thanksgiving.html</guid>
      <description>&lt;p&gt;In honor of Thanksgiving this week, instead of a list of writing from around the web, this week I&amp;rsquo;ll be linking to some of my favorite lesser known software tools, apps and gear.  These are things that let me get things done, and I&amp;rsquo;m thankful for that.&lt;/p&gt;
&lt;h3 id=&#34;javascript-libraries&#34;&gt;JavaScript Libraries&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://www.gatsbyjs.org/&#34;&gt;Gatsby&lt;/a&gt; - I&amp;rsquo;ve written and spoken about Gatsby before, but it keeps getting better as a tool for building React-based web sites and applications.  This blog is written using it.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://date-fns.org/&#34;&gt;date-fns&lt;/a&gt; - date-fns is a nice modular lightweight alternative to &lt;a href=&#34;https://momentjs.com/&#34;&gt;moment.js&lt;/a&gt; for date management in JavaScript.  Because JavaScript&amp;rsquo;s built in dates are weird and hard to work with, and not everybody needs all of the goodness moment provides.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://mobx.js.org/&#34;&gt;MobX&lt;/a&gt; - It&amp;rsquo;s been overshadowed by Redux, but MobX is a fantastic state management library for JavaScript libraries.  Since its an object oriented model that can be used in a variety of ways, it is easier to pull in incrementally&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://glamorous.rocks/&#34;&gt;glamorous&lt;/a&gt; - My favorite CSS-in-JS library for React, it lets you write styles in a few different ways, which allows you to manage things in a very React-y way, without ever getting stuck with things you can&amp;rsquo;t do.&lt;/p&gt;
&lt;h3 id=&#34;apps&#34;&gt;Apps&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://flexibits.com/fantastical&#34;&gt;Fantastical&lt;/a&gt; - The best app I&amp;rsquo;ve ever used for OSX and iPhone&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://mailplaneapp.com/&#34;&gt;Mailplane&lt;/a&gt; - If you like GMail&amp;rsquo;s web app (obviously not to everyone&amp;rsquo;s taste) Mailplane is a great way to use it as a native app on OSX.  I like it because it allows me to use both of my Gmail accounts side by side with their own notification settings and no risk of being lost in a sea of browser tabs.&lt;/p&gt;
&lt;h3 id=&#34;gear&#34;&gt;Gear&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;http://www.rickshawbags.com/commuter-laptop-bag&#34;&gt;Rickshaw Bagworks Commuter Bag&lt;/a&gt; - I&amp;rsquo;ve had the 2.0 version of this bag for the past 4 years, and it has been an amazingly versatile and durable tool for transporting my laptops, notebooks and more.  Highly recommended.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://store.google.com/product/chromecast_2015&#34;&gt;Chromecast&lt;/a&gt; - I have a Chromecast and a Chromecast audio, and they&amp;rsquo;re an amazing cheap way to turn TVs and speakers into &amp;ldquo;Smart devices&amp;rdquo; that you can control from your phone without having to pay for &amp;ldquo;smart devices&amp;rdquo; that probably won&amp;rsquo;t be kept up to date the way you&amp;rsquo;d want.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://amzn.to/2zpBZcm&#34;&gt;Backbeat Fit&lt;/a&gt; - I&amp;rsquo;ve now ended up buying 4 pairs of these headphones for myself and others.  They&amp;rsquo;re fantastic versatile headphones that work great for exercise headphones but are good enough quality to use for other purposes.  I personally have trouble with ear-buds (they don&amp;rsquo;t stay in my ears), so the over-ear style of the fit is perfect for me.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Weekly Links: November 17th 2017</title>
      <link>https://benmccormick.org/2017/11/16/weekly-links-november.html</link>
      <pubDate>Thu, 16 Nov 2017 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2017/11/17/weekly-links-november.html</guid>
      <description>&lt;h3 id=&#34;javascript-and-the-web&#34;&gt;JavaScript And The Web&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;http://2ality.com/2017/11/currying-in-js.html&#34;&gt;Currying In JS | 2ality&lt;/a&gt; - A nice round up of the different approaches for using currying (a functional programming concept) in JavaScript.  My favorite line: &lt;em&gt;&amp;ldquo;One of JavaScript’s best traits is how many different styles of programming it can accommodate.&amp;quot;&lt;/em&gt; This is one of my favorite things about the language as well.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://medium.com/@dhruvrajvanshi/thoughts-on-redux-and-its-similarities-with-oop-6d200f34656&#34;&gt;Thoughts on Redux and its similarities with OOP | Dhruv Rajvanshi&lt;/a&gt; - I always find it useful to understand when core concepts are shared across very different looking tools and paradigms&lt;/p&gt;
&lt;h3 id=&#34;programming-tools-and-practices&#34;&gt;Programming Tools and Practices&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://hacks.mozilla.org/2017/11/entering-the-quantum-era-how-firefox-got-fast-again-and-where-its-going-to-get-faster/&#34;&gt;Entering the Quantum Era—How Firefox got fast again and where it’s going to get faster | Lin Clark&lt;/a&gt; - I&amp;rsquo;ve been using Firefox 57 as my primary browser this week and so far it is very very nice.  Other than a single Chrome-specific extension that I&amp;rsquo;m missing, and a few minor devtool annoyances, everything has worked great.  And it is blazing fast.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://code.visualstudio.com/blogs/2017/11/15/live-share&#34;&gt;Introducing Visual Studio Live Share | Microsoft&lt;/a&gt; and
&lt;a href=&#34;https://blog.atom.io/2017/11/15/code-together-in-real-time-with-teletype-for-atom.html&#34;&gt;Code together in real time with Teletype for Atom | Github&lt;/a&gt;  - In what appears to be a crazy coincidence, both Atom and Visual Studio/Visual Studio Code announced new tools for collaborating with other developers on code, using a google docs-like experience.  Atom&amp;rsquo;s solution is available in beta today, and is a free WebRTC based peer-to-peer solution for editing code together, with the primary user sharing their active tab with anybody who has the uniqueID for your session.  It also includes open-sourcing a library that would let other editors implement its document protocol. Microsoft&amp;rsquo;s solution is more ambitious, supporting both Visual Studio and Visual Studio code, and allowing users access to a whole shared workspace.  It is just an announcement for now though, and it&amp;rsquo;s not clear if it is a peer to peer or centralized solution, nor whether it will have a cost associated with it.  Regardless, both solutions look amazingly cool.&lt;/p&gt;
&lt;blockquote class=&#34;twitter-tweet&#34; data-lang=&#34;en&#34;&gt;&lt;p lang=&#34;en&#34; dir=&#34;ltr&#34;&gt;As one of the three engineers that built Teletype, I share your curiosity! 🙈&lt;/p&gt;&amp;mdash; Jason Rudolph (@jasonrudolph) &lt;a href=&#34;https://twitter.com/jasonrudolph/status/930856578915344384?ref_src=twsrc%5Etfw&#34;&gt;November 15, 2017&lt;/a&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&#34;http://amzn.to/2AVaAjx&#34;&gt;Managing Humans | Michael Lopp (AKA Rands)&lt;/a&gt; - This book was a great roundup of some of the best writings from one of my favorite blogs &lt;a href=&#34;http://randsinrepose.com/&#34;&gt;Rands in Repose&lt;/a&gt;.  Michael Lopp has been a manager and executive at Netscape, Apple, Palantir, Pinterest and now Slack.  He&amp;rsquo;s seen a lot.  While the book is aimed first at managers, it&amp;rsquo;s helpful for anyone who is interested in understanding how engineering teams work, and how to lead or work in one better.&lt;/p&gt;
&lt;h3 id=&#34;non-tech&#34;&gt;Non-Tech&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://www.nytimes.com/2017/11/09/sports/aaron-hernandez-brain-cte.html?_r=0&#34;&gt;On the Table, the Brain Appeared Normal | The New York Times&lt;/a&gt; - Powerful reading about the dangers of football, a sport that I still love watching.  &lt;a href=&#34;https://www.si.com/nfl/2017/09/21/aaron-hernandez-brain-cte-video-photos&#34;&gt;More context here if you&amp;rsquo;re confused after reading the NYT story&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.nytimes.com/2017/11/12/us/nsa-shadow-brokers.html?_r=0&#34;&gt;Security Breach and Spilled Secrets Have Shaken the N.S.A. to Its Core | The New York Times&lt;/a&gt; - Interesting to see such mainstream questioning of the NSA&amp;rsquo;s habit of hording zero-day exploits.  Don&amp;rsquo;t read this one if you want to maintain any naive good feelings about US cybersecurity.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>A Quick Browser Compatibility Checkup</title>
      <link>https://benmccormick.org/2017/11/14/190000.html</link>
      <pubDate>Tue, 14 Nov 2017 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2017/11/15/190000.html</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve written a few times about the state of browser compatibility and the web platform over the years.  Over 4 years ago I &lt;a href=&#34;https://benmccormick.org/2013/06/11/evergreen-browsers&#34;&gt;linked to a post celebrating the rise of evergreen browsers&lt;/a&gt;. Then 2 years ago I was one of several people stressing about &lt;a href=&#34;https://benmccormick.org/2015/06/10/is-safari-being-left-behind/&#34;&gt;whether Safari was going to hold the web back&lt;/a&gt;.  It&amp;rsquo;s something I&amp;rsquo;ve followed closely because supporting many different subtly incompatible execution environments is one of the most unique and frustrating challenges of front-end development.&lt;/p&gt;
&lt;p&gt;The last few years have been really good for web compatibility with Microsoft dumping Internet Explorer in favor of the evergreen Edge, and &lt;a href=&#34;https://babeljs.io/&#34;&gt;Babel&lt;/a&gt; allowing JavaScript developers to write modern JS spec-compliant code and then have it transpiled back into something that runs in a wide variety of environments.  But fairly recently things have started to get even better.&lt;/p&gt;
&lt;p&gt;For the web application I have spent my workdays building over the past 4 years, we target the &lt;a href=&#34;http://browserl.ist/?q=last+2+Chrome+versions%2C+last+2+Safari+versions%2C+last+2+Firefox+versions%2C+last+2+Edge+versions&#34;&gt;last 2 versions of the major desktop browsers&lt;/a&gt; (Chrome, Firefox, Safari, Edge).  At the time of writing that means we target&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Chrome 61 + 62&lt;/li&gt;
&lt;li&gt;Edge 15 + 16&lt;/li&gt;
&lt;li&gt;Firefox 55 + 56&lt;/li&gt;
&lt;li&gt;Safari 10.1 + 11&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I get that for some of you this is a very lax browser support standard, and you&amp;rsquo;re still supporting IE9 or old Android versions.  For others you don&amp;rsquo;t care about browser compatibility at all and are just hacking demos on the newest Chrome.  But &amp;ldquo;last 2 versions&amp;rdquo; is a real world standard that I know plenty of teams target.  And it certainly is a reasonable target for new devs learning about JavaScript and the web.  So let&amp;rsquo;s look at what is natively supported in all targeted browsers if you use this standard today. Spoiler Alert: life is pretty good.&lt;/p&gt;
&lt;h3 id=&#34;available-now&#34;&gt;Available Now&lt;/h3&gt;
&lt;h4 id=&#34;all-of-es6-and-es2016-and-almost-all-of-es2017&#34;&gt;All of ES6 and ES2016, and almost all of ES2017&lt;/h4&gt;
&lt;p&gt;If you&amp;rsquo;re distrustful of Babel and have been holding off on learning the new features that have transformed JavaScript over the past few years until they were &amp;ldquo;browser supported&amp;rdquo;, now is your time.  Other than shared memory and atomics (more on that below), every single feature from the recent updates to the ECMAScript spec is available in the last 2 versions of all 4 major browsers.&lt;/p&gt;
&lt;p&gt;That includes core ES6 stuff like classes, destructuring, and arrow functions.  But also features that were just standardized this summer like &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function&#34;&gt;async functions&lt;/a&gt;.&lt;/p&gt;
&lt;h4 id=&#34;modern-css&#34;&gt;Modern CSS&lt;/h4&gt;
&lt;p&gt;Modern CSS specifications like &lt;a href=&#34;https://css-tricks.com/snippets/css/a-guide-to-flexbox/&#34;&gt;Flexbox&lt;/a&gt;, &lt;a href=&#34;https://css-tricks.com/snippets/css/complete-guide-grid/&#34;&gt;CSS Grid&lt;/a&gt; and &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_variables&#34;&gt;CSS Variables&lt;/a&gt;, and &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/CSS/@supports&#34;&gt;CSS Feature Queries&lt;/a&gt; are all fully supported in these browsers, making creating layouts especially much easier than it had been in the past.&lt;/p&gt;
&lt;h4 id=&#34;promises-and-fetch&#34;&gt;Promises and Fetch&lt;/h4&gt;
&lt;p&gt;Promises have been mostly supported for a while, but they didn&amp;rsquo;t have native support in IE11, so some folks may still be polyfilling them.  With a last 2 versions standard, you not only don&amp;rsquo;t need to polyfill Promises, but also can drop any polyfills for the promise based fetch api as well (and use them with async-await natively!).&lt;/p&gt;
&lt;h3 id=&#34;coming-soon&#34;&gt;Coming Soon&lt;/h3&gt;
&lt;p&gt;So there is a ton of stuff that is available today for people targeting the last 2 versions of browsers.  But there is also a bunch of stuff that is almost there:&lt;/p&gt;
&lt;h4 id=&#34;web-assembly-and-low-level-primitives&#34;&gt;Web Assembly and low level primitives&lt;/h4&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.mozilla.org/blog/2017/11/13/webassembly-in-browsers/&#34;&gt;WebAssembly is now shipping in the latest version of every major browser&lt;/a&gt;.  WebAssembly is a target bytecode for the web that can interop with JavaScript.  Essentially somebody can write C, C++ or Rust code and then compile it to WebAssembly, which runs natively in the browser, potentially much more performantly than equivalent JavaScript code.  The latest version of all browsers also support &lt;a href=&#34;http://2ality.com/2017/01/shared-array-buffer.html&#34;&gt;SharedArrayBuffer and Atomics&lt;/a&gt;, low level APIs for exploring better parallelism support in JavaScript.  In short, it will soon be possible to create much more performant experiences in web browsers than is currently possible.&lt;/p&gt;
&lt;h4 id=&#34;webrtc&#34;&gt;WebRTC&lt;/h4&gt;
&lt;p&gt;The latest versions of all browsers also support WebRTC, an API for peer to peer communication through browsers.  This potentially opens the door for all types of browser-based text/video chat and collaboration applications.&lt;/p&gt;
&lt;h4 id=&#34;service-workers&#34;&gt;Service Workers&lt;/h4&gt;
&lt;p&gt;&lt;a href=&#34;https://jakearchibald.github.io/isserviceworkerready/&#34;&gt;Service workers are getting close&lt;/a&gt;.  They&amp;rsquo;re available in every browser but Safari now, and Safari is working on them.  If we get another big &lt;code&gt;x.1&lt;/code&gt; release of Safari like last year, they could be available for early adopters across the board within the next 6 months.&lt;/p&gt;
&lt;h3 id=&#34;the-web-is-moving-forward-together&#34;&gt;The web is moving forward together&lt;/h3&gt;
&lt;p&gt;It&amp;rsquo;s fun to see this level of unified activity across the web platform over the past 2 years.  In my 7+ years of front-end development, I&amp;rsquo;ve never seen a more compatible web than the one we can develop against today.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Weekly Links: November 10th 2017</title>
      <link>https://benmccormick.org/2017/11/09/weekly-links-november.html</link>
      <pubDate>Thu, 09 Nov 2017 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2017/11/10/weekly-links-november.html</guid>
      <description>&lt;p&gt;I started this new thing last week, &lt;em&gt;Friday Links&lt;/em&gt;.  There&amp;rsquo;s a &lt;a href=&#34;https://goo.gl/forms/MwEtFrDwFWzXSRv13&#34;&gt;feedback form&lt;/a&gt; if you&amp;rsquo;re a regular reader and want to tell me what you think of it.  Otherwise, enjoy the links!&lt;/p&gt;
&lt;h3 id=&#34;javascript-and-the-web&#34;&gt;JavaScript And The Web&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://medium.com/javascript-inside/slaying-a-ui-antipattern-in-react-64a3b98242c&#34;&gt;Slaying a UI Antipattern in React – JavaScript Inside&lt;/a&gt; - This is an interesting case study of how to work through an architectural problem using React.  I love seeing posts like this that take real world scenarios (I deal with this case of having data that might be in one of several loading states all the time), and identify re-usable patterns for solving them.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://jakearchibald.com/2017/netflix-and-react/&#34;&gt;Netflix functions without client-side React, and it’s a good thing - JakeArchibald.com&lt;/a&gt; - A nice look at what Netflix&amp;rsquo;s experience removing client-side react from their landing page means and doesn&amp;rsquo;t mean.  I&amp;rsquo;m going to be really curious to see how the JS community gets better at enabling fast initial experiences while still having full rich interactivity when the users need it.&lt;/p&gt;
&lt;h3 id=&#34;programming-tools-and-practices&#34;&gt;Programming Tools and Practices&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://prettier.io/&#34;&gt;Prettier&lt;/a&gt; - Prettier put out a new release this week and now supports Markdown as well as JavaScript, TypeScript, CSS, and GraphQL.  It has been my favorite new tool of 2017, solving a problem I didn&amp;rsquo;t know I had: the mental overhead of constantly reformatting my own code.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://amzn.to/2zvm12Z&#34;&gt;The Pragmatic Programmer - Andy Hunt &amp;amp; Dave Thomas&lt;/a&gt; - Not a new book at all, but I like to recommend it at every opportunity.  It&amp;rsquo;s my favorite resource on the practice of Software Engineering and well worth checking out if you&amp;rsquo;ve never read it.&lt;/p&gt;
&lt;h3 id=&#34;non-tech&#34;&gt;Non-Tech&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://www.economist.com/news/briefing/21730870-economy-based-attention-easily-gamed-once-considered-boon-democracy-social-media&#34;&gt;Once considered a boon to democracy, social media have started to look like its nemesis - The Economist&lt;/a&gt; - This is a wide-ranging take on the downsides of social media with a focus on it&amp;rsquo;s deleterious effects on our political systems.  If you&amp;rsquo;re on social media and/or you care about the future of politics in your place of living, it is worth a read.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Improving Gatsby Blog Deploy UX</title>
      <link>https://benmccormick.org/2017/11/06/190000.html</link>
      <pubDate>Mon, 06 Nov 2017 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2017/11/07/190000.html</guid>
      <description>&lt;p&gt;About a year ago I switched back to using a static site generator for this blog.  Specifically, I chose &lt;a href=&#34;https://www.gatsbyjs.org/&#34;&gt;Gatsby&lt;/a&gt; and it has been fantastic.  It&amp;rsquo;s incredibly easy to customize and make my own, and I can do fun things like adding metadata to my posts to enable features like the &amp;ldquo;read next&amp;rdquo; list at the bottom of each post, and the &amp;ldquo;most popular&amp;rdquo; posts feature that is actually generated from google analytics data.  The biggest downside of using a static site generator relative to a hosted service though is the annoyance of actually posting.  I could edit or write a post to my &lt;a href=&#34;https://ghost.org/&#34;&gt;Ghost&lt;/a&gt; blog from anywhere, which was a real perk of using that platform.  Until recently I was only able to deploy this site from a single computer, because I needed an API key for Google Analytics to be available.  That has been mostly fine, since I usually work on posts for this site over the course of a few days.&lt;/p&gt;
&lt;p&gt;But last week I decided to start aiming for &lt;a href=&#34;https://benmccormick.org/2017/11/03/friday-links/&#34;&gt;weekly shorter linklog posts&lt;/a&gt;, and that meant having a bit more flexibility with my deploys.  So this week I did 2 things: I set up a &lt;a href=&#34;https://travis-ci.org/&#34;&gt;Travis CI&lt;/a&gt; job to auto-deploy my app when changes hit the master branch, and wrote an initial version of a CLI for managing the blog.  The first version just helps me write out a templated new post.  My setup is pretty tailored to this blog, but I thought it&amp;rsquo;d be helpful to share, and maybe inspire some folks looking to do the same thing for their static site.&lt;/p&gt;
&lt;h3 id=&#34;travis-ci&#34;&gt;Travis CI&lt;/h3&gt;
&lt;p&gt;Travis is a continuous integration environment that is free for open source.  I had used it very minimally for some open source projects, but never to deploy anything so I had to learn about the &lt;code&gt;deploy&lt;/code&gt; option travis provides.  In the end my &lt;code&gt;.travis.yml&lt;/code&gt; file was pretty simple and looked like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yml&#34; data-lang=&#34;yml&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;language&lt;/span&gt;: node_js
&lt;span style=&#34;color:#ff79c6&#34;&gt;node_js&lt;/span&gt;:
- &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;8&amp;#39;&lt;/span&gt;
&lt;span style=&#34;color:#ff79c6&#34;&gt;deploy&lt;/span&gt;:
  &lt;span style=&#34;color:#ff79c6&#34;&gt;skip_cleanup&lt;/span&gt;: &lt;span style=&#34;color:#ff79c6&#34;&gt;true&lt;/span&gt;
  &lt;span style=&#34;color:#ff79c6&#34;&gt;provider&lt;/span&gt;: script
  &lt;span style=&#34;color:#ff79c6&#34;&gt;script&lt;/span&gt;: scripts/deploy.sh
  &lt;span style=&#34;color:#ff79c6&#34;&gt;on&lt;/span&gt;:
    &lt;span style=&#34;color:#ff79c6&#34;&gt;branch&lt;/span&gt;: master
&lt;span style=&#34;color:#ff79c6&#34;&gt;env&lt;/span&gt;:
  &lt;span style=&#34;color:#ff79c6&#34;&gt;global&lt;/span&gt;:
  - ANALYTICS_KEY=./analytics-api-key.json
  - &lt;span style=&#34;color:#ff79c6&#34;&gt;secure&lt;/span&gt;: r43TdsxdDrqYtmZiBmBSe+7u0UBdepMWAYmpTGzGJoAt9p0z+CxcR9ZIj4uMPvBtO3n1wcEvylWcmmY6smu57uXNPhQpyYJaw6HlnfKrz5GjRVX6Ti6oDm8Yyhha1IlcS73dJTpApFis30Kv7fsfDvpNcvVxpF1eDUlw2UAYCwI=
&lt;span style=&#34;color:#ff79c6&#34;&gt;before_install&lt;/span&gt;:
- openssl aes-256-cbc -K $encrypted_dd5d287df7ed_key -iv $encrypted_dd5d287df7ed_iv
  -in analytics-api-key.json.enc -out analytics-api-key.json -d
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Breaking that down a bit:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yml&#34; data-lang=&#34;yml&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;language&lt;/span&gt;: node_js
&lt;span style=&#34;color:#ff79c6&#34;&gt;node_js&lt;/span&gt;:
- &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;8&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I&amp;rsquo;m using node for this project and I want to deploy on node 8, so these lines just make sure I have that environment available.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yml&#34; data-lang=&#34;yml&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;deploy&lt;/span&gt;:
  &lt;span style=&#34;color:#ff79c6&#34;&gt;skip_cleanup&lt;/span&gt;: &lt;span style=&#34;color:#ff79c6&#34;&gt;true&lt;/span&gt;
  &lt;span style=&#34;color:#ff79c6&#34;&gt;provider&lt;/span&gt;: script
  &lt;span style=&#34;color:#ff79c6&#34;&gt;script&lt;/span&gt;: scripts/deploy.sh
  &lt;span style=&#34;color:#ff79c6&#34;&gt;on&lt;/span&gt;:
    &lt;span style=&#34;color:#ff79c6&#34;&gt;branch&lt;/span&gt;: master
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I&amp;rsquo;ve bundled my deploy steps into a script, &lt;code&gt;deploy.sh&lt;/code&gt;.  This config tells travis to run the script after my (currently non-existent) tests have completed, and not to remove any built files before starting the deploy.  It also makes it clear that this should only happen for changes to the master branch.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yml&#34; data-lang=&#34;yml&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;env&lt;/span&gt;:
  &lt;span style=&#34;color:#ff79c6&#34;&gt;global&lt;/span&gt;:
  - ANALYTICS_KEY=./analytics-api-key.json
  - &lt;span style=&#34;color:#ff79c6&#34;&gt;secure&lt;/span&gt;: r43TdsxdDrqYtmZiBmBSe+7u0UBdepMWAYmpTGzGJoAt9p0z+CxcR9ZIj4uMPvBtO3n1wcEvylWcmmY6smu57uXNPhQpyYJaw6HlnfKrz5GjRVX6Ti6oDm8Yyhha1IlcS73dJTpApFis30Kv7fsfDvpNcvVxpF1eDUlw2UAYCwI=
&lt;span style=&#34;color:#ff79c6&#34;&gt;before_install&lt;/span&gt;:
- openssl aes-256-cbc -K $encrypted_dd5d287df7ed_key -iv $encrypted_dd5d287df7ed_iv
  -in analytics-api-key.json.enc -out analytics-api-key.json -d
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This section looks messy, but its all about the environment variables I need for deploying.  Specifically I&amp;rsquo;m pulling in a github key for deploys (thats the secure key), and then also pulling my google analytics key from a json file.  The JSON file is stored as an encrypted file in the directory with a key that only Travis can decrypt.  Then I use a public environment variable to tell my deploy script where to look up the file.  That allows me to set a different path locally and still have local deploys work even though I can&amp;rsquo;t decrypt the checked in JSON file.&lt;/p&gt;
&lt;h3 id=&#34;cli&#34;&gt;CLI&lt;/h3&gt;
&lt;p&gt;I&amp;rsquo;ve started with an extremely basic CLI using &lt;a href=&#34;https://github.com/SBoudrias/Inquirer.js&#34;&gt;Inquirer.js&lt;/a&gt;.  It asks me a series of questions and then generates a markdown doc with the appropriate YAML headings.  Inquirer.js, lodash, and ES6 template strings make this super easy.  It looks like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; inquirer &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; require(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;inquirer&amp;#39;&lt;/span&gt;);
&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; map &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; require(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;lodash/map&amp;#39;&lt;/span&gt;);
&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; find &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; require(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;lodash/find&amp;#39;&lt;/span&gt;);
&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; { mkFile } &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; require(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;../src/utils/file_system&amp;#39;&lt;/span&gt;);
&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; categories &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; require(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;../src/pages/categories.json&amp;#39;&lt;/span&gt;).categories;
&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; moment &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; require(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;moment&amp;#39;&lt;/span&gt;);

&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; dates &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {
  Today&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;0&lt;/span&gt;,
  Tomorrow&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;,
  &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Two Days From Now&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt;,
  &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Three Days From Now&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;3&lt;/span&gt;,
};

inquirer
  .prompt([
    {
      type&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;list&amp;#39;&lt;/span&gt;,
      name&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;type&amp;#39;&lt;/span&gt;,
      message&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;What Type of Post is this&amp;#39;&lt;/span&gt;,
      choices&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; [&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Post&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Page&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Friday-Links&amp;#39;&lt;/span&gt;],
      filter&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; val =&amp;gt; {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; val.toLowerCase();
      },
    },
    {
      type&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;input&amp;#39;&lt;/span&gt;,
      name&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;title&amp;#39;&lt;/span&gt;,
      message&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;What should the title be?&amp;#39;&lt;/span&gt;,
      validate&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; value =&amp;gt; {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (value) {
          &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;true&lt;/span&gt;;
        }
        &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;Title can&amp;#39;t be empty&amp;#34;&lt;/span&gt;;
      },
    },
    {
      type&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;input&amp;#39;&lt;/span&gt;,
      name&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;description&amp;#39;&lt;/span&gt;,
      message&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;What should the description say?&amp;#39;&lt;/span&gt;,
      validate&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; value =&amp;gt; {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (value) {
          &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;true&lt;/span&gt;;
        }
        &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;Description can&amp;#39;t be empty&amp;#34;&lt;/span&gt;;
      },
    },
    {
      type&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;input&amp;#39;&lt;/span&gt;,
      name&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;key&amp;#39;&lt;/span&gt;,
      message&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;What should the post key be?&amp;#39;&lt;/span&gt;,
      validate&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; value =&amp;gt; {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (value) {
          &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;true&lt;/span&gt;;
        }
        &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;Key can&amp;#39;t be empty&amp;#34;&lt;/span&gt;;
      },
    },
    {
      type&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;list&amp;#39;&lt;/span&gt;,
      name&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;category&amp;#39;&lt;/span&gt;,
      message&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;What Category of post is this&amp;#39;&lt;/span&gt;,
      choices&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; map(categories, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;title&amp;#39;&lt;/span&gt;),
      filter&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; title =&amp;gt; {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; find(categories, { title }).key;
      },
    },
    {
      type&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;input&amp;#39;&lt;/span&gt;,
      name&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;tags&amp;#39;&lt;/span&gt;,
      message&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Write out any tags you want to use&amp;#39;&lt;/span&gt;,
    },
    {
      type&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;list&amp;#39;&lt;/span&gt;,
      name&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;date&amp;#39;&lt;/span&gt;,
      message&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;When is this going to be posted&amp;#39;&lt;/span&gt;,
      choices&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; map(dates, (value, key) =&amp;gt; key),
      filter&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; key =&amp;gt; {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; dates[key];
      },
    },
  ])
  .then(answers =&amp;gt; {
    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; postDate &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; moment().add(answers.date, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;days&amp;#39;&lt;/span&gt;);
    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; year &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; postDate.format(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;YYYY&amp;#39;&lt;/span&gt;);
    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; formattedDate &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; postDate.format(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;YYYY/MM/DD&amp;#39;&lt;/span&gt;);
    mkFile(
      &lt;span style=&#34;color:#f1fa8c&#34;&gt;`/src/pages/posts/&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;${&lt;/span&gt;year&lt;span style=&#34;color:#f1fa8c&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;${&lt;/span&gt;answers.key&lt;span style=&#34;color:#f1fa8c&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;.md`&lt;/span&gt;,
      &lt;span style=&#34;color:#f1fa8c&#34;&gt;`---
&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;title: &amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;${&lt;/span&gt;answers.title&lt;span style=&#34;color:#f1fa8c&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;
&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;date: &amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;${&lt;/span&gt;formattedDate&lt;span style=&#34;color:#f1fa8c&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;
&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;permalink: &amp;#34;/&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;${&lt;/span&gt;formattedDate&lt;span style=&#34;color:#f1fa8c&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;${&lt;/span&gt;answers.key&lt;span style=&#34;color:#f1fa8c&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;/&amp;#34;
&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;description: &amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;${&lt;/span&gt;answers.description&lt;span style=&#34;color:#f1fa8c&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;
&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;keywords: &amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;${&lt;/span&gt;answers.tags&lt;span style=&#34;color:#f1fa8c&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;
&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;key: &amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;${&lt;/span&gt;answers.key&lt;span style=&#34;color:#f1fa8c&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;
&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;readNext: &amp;#34;ten-things-js,favorite-interview,jest-matchers-1&amp;#34;
&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;---
&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;    `&lt;/span&gt;
    );
  });
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Inquirer makes it really nice to gather up all the information, then I use a utility I&amp;rsquo;ve already written to dump it in a file.  I want to do a bunch more here in the future here, starting by giving this script the ability to read and parse my existing posts, which will let me enforce uniqueness on names and keys, as well as offer autocomplete on the readNext column, which I&amp;rsquo;ve left hardcoded for now, since its hard to type free form.  There&amp;rsquo;s more to come here, and you all may feel free to steal and remix anything you find useful for your own blogs here.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Weekly Links: November 3rd 2017</title>
      <link>https://benmccormick.org/2017/11/02/weekly-links-november.html</link>
      <pubDate>Fri, 03 Nov 2017 00:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2017/11/03/weekly-links-november.html</guid>
      <description>&lt;p&gt;Today marks the start of a new thing I&amp;rsquo;m trying with this blog: &lt;em&gt;Friday Links&lt;/em&gt; (&lt;strong&gt;Edit: Since renamed to Weekly Links&lt;/strong&gt;).  Every Friday I&amp;rsquo;m going to be gathering some of the best links and content I&amp;rsquo;ve found that week and sharing it here.  It will be primarily but not completely programming focused, with minimal commentary. Some weeks it may be 2-3 links, some weeks it may be 10, but I&amp;rsquo;m going to give it a run at making this a true weekly feature.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re a regular reader (or not) and you have feelings about this, feel free to fill out this &lt;a href=&#34;https://goo.gl/forms/MwEtFrDwFWzXSRv13&#34;&gt;survey&lt;/a&gt; and let me know what you think.  I&amp;rsquo;m still working through how this should work, though eventually it will almost definitely get integrated into the site as a different type of post than my main articles.&lt;/p&gt;
&lt;p&gt;Without further ado, here are this week&amp;rsquo;s Friday links:&lt;/p&gt;
&lt;h3 id=&#34;javascript-and-the-web&#34;&gt;JavaScript And The Web&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.kentcdodds.com/effective-snapshot-testing-e0d1a2c28eca&#34;&gt;Effective Snapshot Testing – Kent Dodds&lt;/a&gt; - This is a great set of practical tips for using snapshot testing well with Jest.  I’m guilty of sometimes making really large snapshots, and as he says here, I’ve found those tests to be useless because the diffs cause eyes to glaze over.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://mobiforge.com/news-comment/safari-service-workers-and-other-pwa-good-news-stories&#34;&gt;Safari service workers and other PWA good news stories - mobiForge&lt;/a&gt; - I’ve never been a big fan of the PWA terminology.  It smells very “marketing-y” to me, in the sense of the word that engineers use as an insult.  Exactly what people mean by a Progressive Web App seems hard to pin down and contextual.  Is it about the technologies used?  The user experience? Is it just that it is installable on phones? Is there a clear checklist that you can check against to see if something is a PWA?  In any case, I am a fan of many of the trends and technology that are getting pushed under the PWA banner, so this article, which discusses how the underlying technologies are being adapted in different places, is indeed good news from my point of view.&lt;/p&gt;
&lt;h3 id=&#34;programming-tools&#34;&gt;Programming Tools&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://stackoverflow.blog/2017/10/31/disliked-programming-languages/&#34;&gt;What are the Most Disliked Programming Languages? - Stack Overflow Blog&lt;/a&gt; -  To be honest, I don’t totally buy the premise of this post.  I don’t think people always list their most disliked languages as the languages they don’t want to work with on Stack Overflow, I think they also list the languages or technologies that people might expect them to work with, but they don’t want to.   Like PHP or CoffeeScript for a web developer, or SQLServer for a DBA. Thats acknowledged but not fully grappled with in the article.  That said, it’s still an interesting dataset, no matter how you label the languages that are being excluded.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://pragprog.com/book/modvim/modern-vim&#34;&gt;Modern Vim - Drew Neil&lt;/a&gt; - Drew Neil’s first book,&lt;a href=&#34;http://amzn.to/2h7tQp3&#34;&gt;Practical Vim&lt;/a&gt;, was my introduction to useful text editing.  I’ve moved off of Vim for my day to day editing over the last few years, but I still plan on buying this book when it goes paperback, because I know I’ll learn at least a few useful tips, and it’s totally possible I’ll be back to Vim as my day to day editor again someday soon.  If you&amp;rsquo;re a Vim user I definitely recommend checking this out.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://wynnnetherland.com/journal/extending-the-command-line/&#34;&gt;Extending the command line - Wynn Netherland&lt;/a&gt; - This is a nice roundup of the various ways you can customize your command line commands to aid in recall, reliability and efficiency.&lt;/p&gt;
&lt;h3 id=&#34;non-tech&#34;&gt;Non-Tech&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://www.nytimes.com/2017/10/30/opinion/when-politics-becomes-your-idol.html?_r=0&#34;&gt;When Politics Becomes Your Idol - The New York Times&lt;/a&gt; - I thought this was an extremely insightful take on the current state of my country&amp;rsquo;s relationship with politics.  How many of us are looking to politics for solutions to problems and seeing it demand more and more for fewer and fewer results?&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://amzn.to/2ipypHO&#34;&gt;The Tech-wise Family - Andy Crouch&lt;/a&gt; - This is a book that is to some extent written for Christians and to some extent written for parents&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;, but I think that it has a lot to offer anyone who has a sneaking suspicion that the tech in their life, while helping with many things, is also distracting them from things that are more valuable.  This book was the most challenging thing I&amp;rsquo;ve read this year, and I highly recommend it.&lt;/p&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;I am a Christian, I am not yet a parent.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>How To Give A Perfectly Adequate Conference Talk</title>
      <link>https://benmccormick.org/2017/10/29/210000.html</link>
      <pubDate>Sun, 29 Oct 2017 22:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2017/10/30/210000.html</guid>
      <description>&lt;p&gt;Tech talks at conferences or meetups generally end up being experienced in one of 4 ways by audience members.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;It&amp;rsquo;s a disaster, and that leads to &lt;strong&gt;rage&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;This person is not just wasting my time, I don&amp;rsquo;t even understand what he&amp;rsquo;s trying to tell me.  Is this a talk about Vue or just him telling his life story?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;The talk is executed just fine, but it misses the mark in some way for the audience, leading to &lt;strong&gt;boredom&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;The first 5 minutes seemed ok, but it didn&amp;rsquo;t catch my attention, and now I&amp;rsquo;ve been on Facebook for 20 minutes and woah are we already wrapping up?  I don&amp;rsquo;t really know how Vue relates to my work.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol start=&#34;3&#34;&gt;
&lt;li&gt;The talk is perfectly adequate, and the audience leaves with some new and useful &lt;strong&gt;knowledge&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;That was really interesting, I&amp;rsquo;ll have to check out Vue soon, it sounds like it would really help me write more maintainable web apps.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol start=&#34;4&#34;&gt;
&lt;li&gt;The talk is incredible and memorable.  It leads to &lt;strong&gt;inspiration&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;Wow I&amp;rsquo;m looking at web development in a whole new way now.  This really changes how I think about my job!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I have no idea how to give a talk that inspires people.  But after speaking a decent amount over the last few years, I&amp;rsquo;ve figured out what helps me give talks that can inform most people, and avoid having people leave bored or enraged.  I want to share what I know, because the truth is that giving a talk at a conference or meetup can be fun and rewarding, and I would love it if you too got the chance to enjoy that.  So here are my tips:&lt;/p&gt;
&lt;h2 id=&#34;the-pitch&#34;&gt;The Pitch&lt;/h2&gt;
&lt;h4 id=&#34;1-show-up&#34;&gt;1. Show up!&lt;/h4&gt;
&lt;p&gt;The only way to give a talk that will interest and inform other people is to actually attempt it.  If you live in a place that has meetups, those are often the easiest place to start.  They&amp;rsquo;re usually run by 1 or 2 people who are going to be grateful to find new folks who are willing to speak. Depending on format, you may be able to give a 5 or 15 minute talk along with other speakers at a meetup to ease into things.  If there&amp;rsquo;s no meetup, you can also apply to conferences.  Almost all conferences have open &amp;ldquo;Call for Papers&amp;rdquo; periods where they invite applications, and many of them try to save some spots for new speakers.  Conference speaking is more of a crapshoot though, since they often have many applications for few spots, and your best bet is to apply widely, and possibly suggest several different talk ideas.  This year I applied to speak at 6 conferences, and actually spoke at 2, and that was by far my best ratio since I started applying to speak a few years ago.&lt;/p&gt;
&lt;h4 id=&#34;2-pick-a-topic-that-youre-interested-in&#34;&gt;2. Pick a topic that you’re interested in&lt;/h4&gt;
&lt;p&gt;Giving a talk can be a fun experience, but it can also be frustrating for both you and the audience.  The best way to suck all of the joy out it is to give a talk about something that you don&amp;rsquo;t care about.  If you&amp;rsquo;re uninterested in the topic, the work to prepare is either going to be a painful grind, or you won&amp;rsquo;t do it.  In which case sitting through your talk may well be a painful grind for your audience.&lt;/p&gt;
&lt;p&gt;Note that I don&amp;rsquo;t say to pick a topic you&amp;rsquo;re passionate about.  Not every talk is going to be the pinnacle of your speaking career, and sometimes there may be nothing out there that is currently changing your life.  You can really help people by sharing the useful, interesting information you have, and this doesn&amp;rsquo;t need to be more than that.&lt;/p&gt;
&lt;h4 id=&#34;3-pick-an-audience-for-whom-that-topic-is-relevant&#34;&gt;3. Pick an audience for whom that topic is relevant&lt;/h4&gt;
&lt;p&gt;So you have a talk topic, and that&amp;rsquo;s great, but does your topic make sense for the people you&amp;rsquo;re speaking to?  Sometimes when you start speaking you may pick a topic before you&amp;rsquo;re sure where you&amp;rsquo;re going to give the talk, other times you may have a place you want to speak, and you need to pick a topic for it.  Either way, make sure that you end up with a topic and an audience that match.  If you&amp;rsquo;re talking to a group of beginner web programmers, a deep dive into the Rust memory model might not be the best choice.  If you&amp;rsquo;re speaking to veteran python programmers, a talk about the basics of object oriented programming might miss its mark.&lt;/p&gt;
&lt;p&gt;Sometimes you may not know your audience exactly.  This is especially true for speaking at large multi-track conferences, where there may be developers (and/or non-developers) from a variety of backgrounds.  In this case, you&amp;rsquo;ll still want to pick the audience you want to target (some subset of the group you know may be there), and then make sure to do a good job of following point #6 below.&lt;/p&gt;
&lt;h4 id=&#34;4-pick-a-main-takeaway-for-your-audience&#34;&gt;4. Pick a “main takeaway” for your audience&lt;/h4&gt;
&lt;p&gt;It&amp;rsquo;s not enough to just have a topic and audience that generally match.  You&amp;rsquo;re also going to want to know what you want the audience to get out of it.  Talking about &amp;ldquo;debugging&amp;rdquo; to a JavaScript audience could be a good talk, but do you want them to learn&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;how to use Chrome devtools to find performance bugs?&lt;/li&gt;
&lt;li&gt;a repeatable step by step workflow for figuring out any bug?&lt;/li&gt;
&lt;li&gt;a story about how you solved a specific bug?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Unlike the &amp;ldquo;topic&amp;rdquo;, the takeaway should be pretty specific.  Given the audience that you&amp;rsquo;re targeting, what piece(s) of new information do you want them to receive as they walk away from your talk?&lt;/p&gt;
&lt;h4 id=&#34;5-pick-a-talk-format&#34;&gt;5. Pick a talk format&lt;/h4&gt;
&lt;p&gt;There are a few main formats that most tech talks fall into:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Present a problem, describe several possible solutions (possibly recommending one)&lt;/li&gt;
&lt;li&gt;Present a tool, explain what problems it solves and give examples of using it&lt;/li&gt;
&lt;li&gt;Present an idea or way of looking at things, and show how it applies in different situations&lt;/li&gt;
&lt;li&gt;Tell your story. Explain how a certain technology, idea, or problem in the tech community has affected your life.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All of these formats can work, for a first talk I&amp;rsquo;d recommend one of the first 2, keeping things concrete and making it easier to get to that &amp;ldquo;main takeaway&amp;rdquo;.&lt;/p&gt;
&lt;h4 id=&#34;6-write-a-description-that-tells-your-audience-what-to-expect&#34;&gt;6. Write a description that tells your audience what to expect&lt;/h4&gt;
&lt;p&gt;The final step of putting together a pitch is writing a description that accurately lets attendees know what to expect.  A great title and description do a few things.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You actually have something to submit to a meetup organizer or a conferences call for papers.&lt;/li&gt;
&lt;li&gt;A good description helps ground you as you prepare the content of the talk.  You can look at your slides and see if you&amp;rsquo;re actually focusing on the things you wanted to communicate&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/li&gt;
&lt;li&gt;A well written title and description will help attract your target audience to your talk.  If you&amp;rsquo;re giving a talk for beginners or advanced users, or users of a particular technology, make sure that&amp;rsquo;s clear in the description.  People go out of their way to go to talks where they know they&amp;rsquo;re the target audience, and nothing kills the mood of a talk than a situation where the talk isn&amp;rsquo;t relevant to most of the audience.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Note that in general, a good description matters more than the exact title of the talk, but if you&amp;rsquo;re at a multi-track conference, make sure to give a descriptive title, as conferences will often only include the talk name in their schedules, without a top-level description.  Naming your talk about the creative uses of Golang &amp;ldquo;Go-ing Crazy&amp;rdquo; is fine for a Go meetup, but if people are going to be choosing what session to attend based on your talks name, something more descriptive would be nice, even if it has a little less personality.&lt;/p&gt;
&lt;h2 id=&#34;the-preparation&#34;&gt;The Preparation&lt;/h2&gt;
&lt;h4 id=&#34;7-have-slides&#34;&gt;7. Have slides&lt;/h4&gt;
&lt;p&gt;I&amp;rsquo;ve seen some amazing live-coding talks.  I&amp;rsquo;ve given one myself at a meetup.  There is definitely a place for them, as well as for minimally visual talks with 2-3 slides.  But if you&amp;rsquo;re aiming for informative, structuring your talk around a good slide deck is your best bet.&lt;/p&gt;
&lt;p&gt;Slides shouldn&amp;rsquo;t have too much information: they&amp;rsquo;re the backbone of your talk, and aren&amp;rsquo;t meant to stand alone&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;.  Instead, they provide structure both for you and the audience as you move through your presentation.&lt;/p&gt;
&lt;h4 id=&#34;8-have-a-talk-track&#34;&gt;8. Have a talk track&lt;/h4&gt;
&lt;p&gt;Slides are good, but they&amp;rsquo;re just the start.  You need a talk track that is more than just &amp;ldquo;reading off my slides&amp;rdquo;.  To feel really well prepared for a talk, I usually write out a complete script for the talk that I intend to follow, and then edit that after several practice run throughs.  For the actual talk I usually boil most of that script down to bullet points to keep me focused.  There will be some experimentation needed there to figure out what works best for you.&lt;/p&gt;
&lt;h4 id=&#34;9-make-sure-your-av-setup-works&#34;&gt;9. Make sure your A/V setup works!&lt;/h4&gt;
&lt;p&gt;I was reminded just last week about the importance of testing that you can give your talk in the venue you&amp;rsquo;re speaking at with the equipment you have as early as possible.  I was forced to give a talk last week on my manager&amp;rsquo;s laptop after mine failed to connect to the venue&amp;rsquo;s projector.  It ended up being a dumb problem on my side that I could have solved if I&amp;rsquo;d verified my setup earlier and had more time to figure things out.  So that&amp;rsquo;s my a/v setup parable.  The things to remember here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Show up early and test your setup if at all possible (event organizers are usually happy to help with this and may insist on this)&lt;/li&gt;
&lt;li&gt;Bring your own adapters.  In the US, at least be ready to connect to HDMI and VGA.  I can&amp;rsquo;t speak to what might be common internationally, but at the very least it&amp;rsquo;s good to be paranoid&lt;/li&gt;
&lt;li&gt;Make sure to bring a power cable.  Your slides going black in the middle of your talk is not a good look.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;the-delivery&#34;&gt;The Delivery&lt;/h2&gt;
&lt;h4 id=&#34;10-have-notes&#34;&gt;10. Have notes&lt;/h4&gt;
&lt;p&gt;So now it is time to actually give your talk.  Make sure to bring notes.  Most presentation software programs like Powerpoint and Keynote have nice built in presenter note features for this (make sure to practice setting it up so that you see the notes and the audience just sees the slide). You also can just use paper notes in a notebook. Notes are important to keep you on track in case you freeze, and may be something you just want to read for portions of the talk.&lt;/p&gt;
&lt;p&gt;Here again you have several choices for how to handle notes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You can read your talk from a script. This lowers your ability to connect with your audience, but it is low risk, and you&amp;rsquo;ll guarantee that you&amp;rsquo;ll hit the content you intend to.  As a native english speaker, I probably underrate this a bit too.  If you&amp;rsquo;re presenting in a second language and reading can help you confidently deliver the material, it may be worth doing so.&lt;/li&gt;
&lt;li&gt;You can work off of bullet point notes, which were ideally pulled out of a full script that you wrote originally.  So you&amp;rsquo;re talking naturally, with some notes to give you structure and help pull you back in if you&amp;rsquo;re fumbling around.&lt;/li&gt;
&lt;li&gt;You can memorize your talk verbatim.  This is hard and high risk (if you forget something it can become an awkward stumble as you try to get back to your script), but has a chance at being a very compelling experience&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I have found that bullet point notes work well for me, but if you&amp;rsquo;re great at memorizing things, or would be more comfortable reading and are ok with sacrificing some connection to the audience, all 3 can work.&lt;/p&gt;
&lt;h4 id=&#34;11-give-context-and-set-expectations-again&#34;&gt;11. Give context and set expectations (again)&lt;/h4&gt;
&lt;p&gt;At the start of your talk, you want to answer 3 questions:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Who are you?&lt;/li&gt;
&lt;li&gt;Who is this for?&lt;/li&gt;
&lt;li&gt;What are you going to be talking about?&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You may think you answered these questions with your description, but there will definitely be people at your talk who didn&amp;rsquo;t read your description, and others who misread it.  Giving context at the beginning of your talk helps people prepare to hear the things that matter in your talk.  If this is a conference, it lets people decide whether they want to stay for your talk or not.  Don&amp;rsquo;t be discouraged if some people walk out of your talk after your explanation.  That&amp;rsquo;s a sign that you&amp;rsquo;ve done a good job clarifying the scope of your talk, and honoring their time. Having those folks leave now will be a much better experience than having them staring at Facebook and distracting others through out your talk, and it is now more likely that the people in front of you are the audience you wanted to address.&lt;/p&gt;
&lt;h4 id=&#34;12-be-confident-and-grateful&#34;&gt;12. Be Confident and Grateful&lt;/h4&gt;
&lt;p&gt;When you know your topic and you&amp;rsquo;ve prepared well, the actual speaking part will usually end up being the easiest part.  So be confident.  Not because you&amp;rsquo;re already a great speaker, or because of some feeling of baseless optimism, but because you&amp;rsquo;ve done the work to be ready and you have the structure around you to succeed.  Also make sure to be grateful.  A bunch of people showed up to hear you speak.  Appreciate them, give them your best and hopefully try to answer their questions.  Speaking is a great opportunity, and I hope you get the chance to try it.&lt;/p&gt;
&lt;h3 id=&#34;more-resources&#34;&gt;More Resources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Rands has a &lt;a href=&#34;http://randsinrepose.com/archives/out-loud/&#34;&gt;great post&lt;/a&gt; on preparing for a presentation.  Lots of great little details in there.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.papercall.io/events&#34;&gt;Papercall.io&lt;/a&gt; is a great way to find conferences that are looking for speakers&lt;/li&gt;
&lt;li&gt;If you&amp;rsquo;re not already connected with local meetup/interest groups, take a look at &lt;a href=&#34;https://www.meetup.com/&#34;&gt;Meetup.com&lt;/a&gt; and see if there are any in your area.&lt;/li&gt;
&lt;/ul&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;It&amp;rsquo;s ok to change your description later if things change as you prep the talk.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;People will often ask for the slides of my talk after I give them.  I usually link them, since people ask, but the slides on their own really aren&amp;rsquo;t a substitute for the talk (and if they are informative to that level, the talk will probably suffer as the audience tries to take in too much information).&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>Taking Advantage of Jest Matchers (Part 2)</title>
      <link>https://benmccormick.org/2017/09/04/220000.html</link>
      <pubDate>Mon, 04 Sep 2017 23:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2017/09/05/220000.html</guid>
      <description>&lt;p&gt;&lt;em&gt;This post continues my look at Jest matchers from &lt;a href=&#34;https://benmccormick.org/2017/08/15/jest-matchers-1/&#34;&gt;Part 1&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;In part 1 I covered the first 4 types of Jest matchers.  In this post I&amp;rsquo;m going to cover &lt;em&gt;contains&lt;/em&gt; matchers, &lt;em&gt;async&lt;/em&gt; matchers, &lt;em&gt;snapshot&lt;/em&gt; matchers, &lt;em&gt;function&lt;/em&gt; matchers and &lt;em&gt;meta&lt;/em&gt; matchers, as well as looking at a few extra tips and tricks for using matchers.&lt;/p&gt;
&lt;h3 id=&#34;contains-matchers&#34;&gt;Contains Matchers&lt;/h3&gt;
&lt;p&gt;Contains matchers are exactly what they sound like.  They&amp;rsquo;re matchers that check to see if an array contains an item or if a string contains a substring.&lt;/p&gt;
&lt;h4 id=&#34;tocontain-and-tocontainequal&#34;&gt;toContain and toContainEqual&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;toContain&lt;/code&gt; and &lt;code&gt;toContainEqual&lt;/code&gt; both check to see if a value is contained inside of an array or string.  When used against a string, they are both equivalent and check to see if a passed string is a substring of the expression being tested.  This means they serve as a more limited version of &lt;code&gt;toMatch&lt;/code&gt; that will only take a substring and not a regex.  When used against an array or array-like object, &lt;code&gt;toContain&lt;/code&gt; looks for matches using strict equality while &lt;code&gt;toContainEqual&lt;/code&gt; looks for matches using recursive equality&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.  In practice that looks like&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;// toContain does exact matches
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;expect([&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;c&amp;#39;&lt;/span&gt;]).toContain(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;) &lt;span style=&#34;color:#6272a4&#34;&gt;// true
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;expect({&lt;span style=&#34;color:#bd93f9&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;, length&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt;}).toContain(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;); &lt;span style=&#34;color:#6272a4&#34;&gt;// true
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;expect(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;abc&amp;#39;&lt;/span&gt;).toContain(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;ab&amp;#39;&lt;/span&gt;); &lt;span style=&#34;color:#6272a4&#34;&gt;// true
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;expect(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;abc&amp;#39;&lt;/span&gt;).not.toContain(&lt;span style=&#34;color:#f1fa8c&#34;&gt;/a/&lt;/span&gt;); &lt;span style=&#34;color:#6272a4&#34;&gt;// true
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;expect([{a&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;bc&amp;#39;&lt;/span&gt;}, {b&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;cd&amp;#39;&lt;/span&gt;}]).not.toContain({a&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;bc&amp;#39;&lt;/span&gt;}); &lt;span style=&#34;color:#6272a4&#34;&gt;// true
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;
&lt;span style=&#34;color:#6272a4&#34;&gt;// toContainEqual does recursive matches
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;expect([&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;c&amp;#39;&lt;/span&gt;]).toContainEqual(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;) &lt;span style=&#34;color:#6272a4&#34;&gt;// true
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;expect([{a&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;bc&amp;#39;&lt;/span&gt;}, {b&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;cd&amp;#39;&lt;/span&gt;}]).toContainEqual({a&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;bc&amp;#39;&lt;/span&gt;}); &lt;span style=&#34;color:#6272a4&#34;&gt;// true
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;async-matchers&#34;&gt;Async Matchers&lt;/h3&gt;
&lt;p&gt;Async matchers handle testing functions that have an asynchronous component.  We&amp;rsquo;ll look at &lt;code&gt;resolves&lt;/code&gt; and &lt;code&gt;rejects&lt;/code&gt; for testing Promises.  But first, it is worth noting that any matcher can be used for asynchronous testing if necessary.  You just have to use the callback option that is passed to each test function, like so:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;test(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Delayed Test&amp;#39;&lt;/span&gt;, done =&amp;gt; {
  &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; delayedEval &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; condition =&amp;gt; () =&amp;gt; {
    expect(condition).toBe(&lt;span style=&#34;color:#ff79c6&#34;&gt;true&lt;/span&gt;);
    done();
  }
  setTimeout(delayedEval(&lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;===&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;), &lt;span style=&#34;color:#bd93f9&#34;&gt;0&lt;/span&gt;) &lt;span style=&#34;color:#6272a4&#34;&gt;// true
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;})
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Jest detects whether the &lt;code&gt;done&lt;/code&gt; callback has been defined for the function, and if it is waits for 5 seconds to see if &lt;code&gt;done&lt;/code&gt; is called before failing, and evaluates any
asynchronous expects that occur before then.  This behavior is inherited from Jasmine, and works ok, but can be a bit difficult to work with.  Jest makes this easier in 2 ways.  First with a set of special matchers for working with promises, and second with a set of meta matchers that can make async tests more reliable.  We&amp;rsquo;ll get to the meta matchers in a second, but first we&amp;rsquo;ll look at the promise matchers.&lt;/p&gt;
&lt;h4 id=&#34;resolves-rejects&#34;&gt;.resolves, .rejects&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;resolves&lt;/code&gt; and &lt;code&gt;rejects&lt;/code&gt; are chaining matchers like &lt;code&gt;not&lt;/code&gt; that let you write async tests with Promises.  Using &lt;code&gt;resolves&lt;/code&gt; to rewrite the previous example looks like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;test(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Delayed Test with promises&amp;#39;&lt;/span&gt;, () =&amp;gt; {
  &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; testPromise &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;Promise&lt;/span&gt;((res, rej) =&amp;gt; {
      setTimeout(() =&amp;gt; res(&lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;===&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;), &lt;span style=&#34;color:#bd93f9&#34;&gt;0&lt;/span&gt;);
  });
  expect(testPromise).resolves.toBe(&lt;span style=&#34;color:#ff79c6&#34;&gt;true&lt;/span&gt;); &lt;span style=&#34;color:#6272a4&#34;&gt;// true
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;})
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This waits for the promise to resolve, and then compares the resolved output with &lt;code&gt;toBe&lt;/code&gt;.  If a rejection is expected, you can replace &lt;code&gt;resolves&lt;/code&gt; with &lt;code&gt;rejects&lt;/code&gt; for a similar test. This ends up being much clearer in my opinion than the callback-based async tests, since the assertion is much more direct, and you don&amp;rsquo;t have to worry about cases where &lt;code&gt;done&lt;/code&gt; might not be called where it should be.&lt;/p&gt;
&lt;h3 id=&#34;meta-matchers&#34;&gt;Meta Matchers&lt;/h3&gt;
&lt;p&gt;Meta matchers pair well with the &lt;code&gt;done&lt;/code&gt; async matchers above, if you have to use them.  They just let you test that all of your assertions have actually run. The first one, &lt;code&gt;expect.assertions&lt;/code&gt; tests that a specific number of assertions have been run at that point in the test.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;test(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;records have a name and an ID&amp;#39;&lt;/span&gt;, () =&amp;gt; {
    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; record &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; getRecord(&lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;);
    expect(record).toHaveProperty(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;id&amp;#39;&lt;/span&gt;);  
    expect.assertions(&lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;);  &lt;span style=&#34;color:#6272a4&#34;&gt;// true
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    expect(record).toHaveProperty(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;fullName&amp;#39;&lt;/span&gt;);
    expect.assertions(&lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt;);  &lt;span style=&#34;color:#6272a4&#34;&gt;// true
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;})
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This can be useful for async tests to make sure things have run correctly before calling &lt;code&gt;done()&lt;/code&gt;, for tests with conditional logic to make sure that the logic played out as expected, and for normal tests as an extra paranoid quality check to make sure that tests aren&amp;rsquo;t accidentally deleted.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;expect.hasAssertions&lt;/code&gt; is just a simpler version of this test that checks that you&amp;rsquo;ve asserted something in the test.  It&amp;rsquo;s useful for the same things as &lt;code&gt;expect.assertions&lt;/code&gt; but will be a little less reliable and also a bit less fragile when tests change.&lt;/p&gt;
&lt;p&gt;Note that neither &lt;code&gt;expect.assertions&lt;/code&gt; nor &lt;code&gt;expect.hasAssertions&lt;/code&gt; count as assertions themselves and don&amp;rsquo;t contribute to the assertion count.&lt;/p&gt;
&lt;h3 id=&#34;snapshot-matchers&#34;&gt;Snapshot Matchers&lt;/h3&gt;
&lt;p&gt;Snapshot testing is one of Jest&amp;rsquo;s signature features.  It&amp;rsquo;s been described in depth in many other places, including &lt;a href=&#34;https://benmccormick.org/2016/09/19/testing-with-jest-snapshots-first-impressions/&#34;&gt;on this blog&lt;/a&gt;.  If you&amp;rsquo;re unfamiliar with snapshot testing, I recommend checking out one of those deeper posts.  But at a high level, snapshots are an assertion that data has remained the same since the last time a test was run.  Jest has serializers for a bunch of built in data types and React components. But it&amp;rsquo;s possible to define serializers for different data types to determine how that data should be represented in a snapshot.&lt;/p&gt;
&lt;p&gt;The core snapshot function, &lt;code&gt;toMatchSnapshot()&lt;/code&gt; is fairly simple to explain. When run the first time, &lt;code&gt;toMatchSnapshot&lt;/code&gt; takes the string representation of the data passed to it (generated by whatever serializer is used for that data type) and writes it to a snapshot file.  After the snapshot has been written once, future runs of &lt;code&gt;toMatchSnapshot&lt;/code&gt; behave differently.  If Jest is run normally, &lt;code&gt;toMatchSnapshot&lt;/code&gt; compares the serialized data to the value in the snapshot file, and fails the test if they are different.  If Jest is run with the &lt;code&gt;-u&lt;/code&gt; option, it will instead update the snapshot file with the current serialized value.  This behavior lets us write tests that don&amp;rsquo;t have a pre-defined &amp;ldquo;correct value&amp;rdquo;, instead we can use our test cases to see what has changed, and choose to accept it or not.&lt;/p&gt;
&lt;h4 id=&#34;tothrowerrormatchingsnapshot&#34;&gt;toThrowErrorMatchingSnapshot&lt;/h4&gt;
&lt;p&gt;In addition to &lt;code&gt;toMatchSnapshot&lt;/code&gt;, Jest offers a second snapshot matcher, &lt;code&gt;toThrowErrorMatchingSnapshot&lt;/code&gt;, which catches errors and verifies that they match a snapshot, similar to the &lt;code&gt;toThrow&lt;/code&gt; matcher I described in part 1.&lt;/p&gt;
&lt;h3 id=&#34;function-matchers&#34;&gt;Function Matchers&lt;/h3&gt;
&lt;p&gt;One of Jest&amp;rsquo;s nicer features is its function mocking system.  A full discussion of function mocking is outside the scope of this post, but suffice it to say that you can create &amp;ldquo;tracked&amp;rdquo; functions in Jest.  The following matchers work with those tracked functions to verify behavior, using an example of a function that takes another function and calls it with the given arguments.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; executeFn &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; (fn, ...args) =&amp;gt; fn(...args)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;tohavebeencalled-tohavebeencalledtimes&#34;&gt;toHaveBeenCalled, toHaveBeenCalledTimes&lt;/h4&gt;
&lt;p&gt;The most basic matcher when dealing with functions is &lt;code&gt;toHaveBeenCalled&lt;/code&gt;.  It works more or less how it sounds, and determines whether a function has executed during the test.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;test(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;does executeFn run the function passed to it?&amp;#39;&lt;/span&gt;, () =&amp;gt; {
  &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; fn &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; jest.fn();
  executeFn(fn);
  expect(fn).toHaveBeenCalled();
})
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Jest also has a related matcher, &lt;code&gt;toHaveBeenCalledTimes&lt;/code&gt; which lets you specify how many times a function has been called.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;test(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;does executeFn run the function passed to it only once?&amp;#39;&lt;/span&gt;, () =&amp;gt; {
  &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; fn &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; jest.fn();
  executeFn(fn);
  expect(fn).toHaveBeenCalledTimes(&lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;);
})
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;tohavebeencalledwith-tohavebeenlastcalledwith&#34;&gt;toHaveBeenCalledWith, toHaveBeenLastCalledWith&lt;/h4&gt;
&lt;p&gt;Sometimes you don&amp;rsquo;t just want to know if a function was called, but want to make sure that it was called with the right arguments.  Jest has you covered.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;test(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;does executeFn run the function with the passed arguments&amp;#39;&lt;/span&gt;, () =&amp;gt; {
  &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; fn &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; jest.fn();
  executeFn(fn, &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;, &lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt;);
  expect(fn).toHaveBeenCalledWith(&lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;, &lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt;);
})
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;toHaveBeenCalledWith&lt;/code&gt; lets you check that the function was called with the right arguments.  You have to be careful though, if the function was called multiple times, you&amp;rsquo;re only verifying that it was called with those arguments at some point.  If you want to get more specific, you can use &lt;code&gt;toHaveBeenLastCalledWith&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;test(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;does executeFn run the function with the passed arguments&amp;#39;&lt;/span&gt;, () =&amp;gt; {
  &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; fn &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; jest.fn();
  executeFn(fn, &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;, &lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt;);
  executeFn(fn, &lt;span style=&#34;color:#bd93f9&#34;&gt;3&lt;/span&gt;, &lt;span style=&#34;color:#bd93f9&#34;&gt;4&lt;/span&gt;);
  expect(fn).toHaveBeenCalledWith(&lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;, &lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt;); &lt;span style=&#34;color:#6272a4&#34;&gt;// true
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;  expect(fn).not.toHaveBeenLastCalledWith(&lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;, &lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt;); &lt;span style=&#34;color:#6272a4&#34;&gt;// true
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;})
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;bonus-content&#34;&gt;Bonus Content&lt;/h3&gt;
&lt;p&gt;That&amp;rsquo;s all for matcher methods, but there are a few other helpful things to know about matchers that I didn&amp;rsquo;t get to work into any of the matcher categories.  So here you go:&lt;/p&gt;
&lt;h3 id=&#34;extension-methods&#34;&gt;Extension Methods&lt;/h3&gt;
&lt;p&gt;Jest&amp;rsquo;s expect object has 2 methods for extending what it can do: &lt;code&gt;expect.addSnapshotSerializer&lt;/code&gt; and &lt;code&gt;expect.extend&lt;/code&gt;.  &lt;code&gt;expect.addSnapshotSerializer&lt;/code&gt; lets you add a new snapshot serializer as a one off for a specific test file. A serializer is simply an object that defines &lt;code&gt;test&lt;/code&gt; and &lt;code&gt;print&lt;/code&gt; methods.  You can learn more &lt;a href=&#34;http://facebook.github.io/jest/docs/en/configuration.html#snapshotserializers-array-string&#34;&gt;in the docs&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;expect.extend&lt;/code&gt; allows you to define custom matchers!  It takes an object with methods that define the new matchers to add.  Each method should be a function that takes the expected value as a first argument, and then expected arguments to the matcher as the rest of the arguments.  For instance, here is a matcher to see whether a string is a palindrome.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;expect.extend({
  toBeAPalindrome(received) {
    &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#ff79c6&#34;&gt;typeof&lt;/span&gt; received &lt;span style=&#34;color:#ff79c6&#34;&gt;!==&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;string&amp;#39;&lt;/span&gt;) {
      &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;expected ${received} to be a string, but it was a ${typeof received}&amp;#39;&lt;/span&gt;;
    }
    &lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; reversed &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; received.split(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;).reverse().join(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;);
    &lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; pass &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; received &lt;span style=&#34;color:#ff79c6&#34;&gt;===&lt;/span&gt; reversed;
    &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (pass) {
      &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; {
        message&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; () =&amp;gt; (
          &lt;span style=&#34;color:#f1fa8c&#34;&gt;`expected &lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;${&lt;/span&gt;received&lt;span style=&#34;color:#f1fa8c&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt; not to be a palindrome`&lt;/span&gt;
        ),
        pass&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;true&lt;/span&gt;,
      };
    } &lt;span style=&#34;color:#ff79c6&#34;&gt;else&lt;/span&gt; {
      &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; {
        message&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; () =&amp;gt; (&lt;span style=&#34;color:#f1fa8c&#34;&gt;`expected &lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;${&lt;/span&gt;received&lt;span style=&#34;color:#f1fa8c&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt; to be a palindrome but it was &lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;${&lt;/span&gt;reversed&lt;span style=&#34;color:#f1fa8c&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt; when reversed`&lt;/span&gt;),
        pass&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;false&lt;/span&gt;,
      };
    }
  },
});

test(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Anna is a palindrome&amp;#39;&lt;/span&gt;, () =&amp;gt; {
  expect(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;anna&amp;#39;&lt;/span&gt;).toBeAPalindrome(); &lt;span style=&#34;color:#6272a4&#34;&gt;// true
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;  expect(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;ann&amp;#39;&lt;/span&gt;).not.toBeAPalindrome(); &lt;span style=&#34;color:#6272a4&#34;&gt;// true
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;matcher-wildcards&#34;&gt;Matcher Wildcards&lt;/h3&gt;
&lt;p&gt;Several of the matchers I&amp;rsquo;ve described in these posts are focused on equality of a particular part of a structure. These include the template matchers, contains matchers, and the &lt;code&gt;toEqual&lt;/code&gt; matcher.  In these cases you&amp;rsquo;re trying to say that some part of an object is equal to something else.  But sometimes you want to be a bit open-minded about part of that.  Maybe you want to ensure that an object has an &lt;code&gt;email&lt;/code&gt; property that is a string with the character &lt;code&gt;@&lt;/code&gt; in it , or that it has a name property defined, but that could be anything as long as its defined.  Jest has wildcards that help you do this.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;expect.any(&amp;lt;constructor&amp;gt;)&lt;/code&gt; lets you match any object of a specific type&lt;/li&gt;
&lt;li&gt;&lt;code&gt;expect.anything()&lt;/code&gt; matches anything except null and undefined&lt;/li&gt;
&lt;li&gt;&lt;code&gt;expect.stringMatching(regexp)&lt;/code&gt; matches any string that matches the regex you pass it&lt;/li&gt;
&lt;li&gt;&lt;code&gt;expect.stringContaining(string)&lt;/code&gt; matches strings against a substring&lt;/li&gt;
&lt;li&gt;&lt;code&gt;expect.arrayContaining(array)&lt;/code&gt; matches arrays that have a specific set of values in them&lt;/li&gt;
&lt;li&gt;&lt;code&gt;expect.objectContaining(object)&lt;/code&gt; matches objects that have a specific set of key/value pairs&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Using wildcards looks like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;test(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;wildcard example&amp;#39;&lt;/span&gt;, () =&amp;gt; {

  expect(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;test&amp;#39;&lt;/span&gt;).toEqual(expect.anything()); &lt;span style=&#34;color:#6272a4&#34;&gt;// true
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;
  expect({foo&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; [&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;test&amp;#39;&lt;/span&gt;]}).toMatchObject({
    foo&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; expect.arrayContaining([&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;test&amp;#39;&lt;/span&gt;])
  }); &lt;span style=&#34;color:#6272a4&#34;&gt;// true
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;expect-outside-of-jest&#34;&gt;expect outside of Jest&lt;/h3&gt;
&lt;p&gt;As I was finishing up this post, Jest 21 was released, along with the exciting news that &lt;code&gt;jest-matchers&lt;/code&gt; has been renamed to &lt;code&gt;expect&lt;/code&gt; and is now available as a standalone module that can be used in other test frameworks, including in the browser.  So if the matchers in these blog posts have looked appealing to you, but you have an existing test framework that you&amp;rsquo;re tied to, feel free to check it out &lt;a href=&#34;https://www.npmjs.com/package/expect&#34;&gt;on npm&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;more-resources&#34;&gt;More Resources&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;The latest info on all of these matcher APIs is always going to be in their very readable &lt;a href=&#34;http://facebook.github.io/jest/docs/en/expect.html&#34;&gt;docs&lt;/a&gt;.  Check them out for more examples and good links to a deeper dive on some of the other topics that these posts have touched on, like snapshot testing and mock functions.&lt;/li&gt;
&lt;/ul&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;Similar to toBe and toEqual from part 1, strict equality here means it&amp;rsquo;s the same reference and is equivalent to &lt;code&gt;x === y&lt;/code&gt;, while recursive equality means the object&amp;rsquo;s are structured the same and any object with the same structure and values will be considered equal.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>Taking Advantage of Jest Matchers (Part 1)</title>
      <link>https://benmccormick.org/2017/08/14/230000.html</link>
      <pubDate>Tue, 15 Aug 2017 00:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2017/08/15/230000.html</guid>
      <description>&lt;p&gt;Back in May, my favorite testing library, Jest, released it&amp;rsquo;s 20th version and &lt;a href=&#34;https://facebook.github.io/jest/blog/2017/05/06/jest-20-delightful-testing-multi-project-runner.html&#34;&gt;rebranded itself&lt;/a&gt; as the library for &amp;ldquo;Delightful JavaScript Testing&amp;rdquo;.  Delightful and testing are two words that usually don&amp;rsquo;t go together in the software development lexicon.  But that claim is the result of 2 years of hard work from the Jest team trying to get the usability details of testing exactly right.  One of the version 20 announcements that exemplified this commitment to detail was the addition of several new assertion APIs to an already large list. This post dives into the many matcher options in Jest, why they&amp;rsquo;re there, and how to make good use of them.&lt;/p&gt;
&lt;p&gt;Assertion APIs, or matchers, are the methods that the library makes available for defining the expected value of a variable or expression.  The most basic assertion in Jest is the &lt;code&gt;.toBe&lt;/code&gt; matcher, which checks to see if one value is the same as the other.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;test(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Math still works&amp;#39;&lt;/span&gt;, () =&amp;gt; {
  expect(&lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;).toBe(&lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt;);
})
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;why-so-many-matchers&#34;&gt;Why so many matchers?&lt;/h3&gt;
&lt;p&gt;When writing tests, the only assertion api you really &lt;strong&gt;need&lt;/strong&gt; is a method that takes a boolean and determines whether it is true or false.  Assuming you can figure out inspecting functions and async code, everything else can be expressed with an assert method like that:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;test(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Math still works&amp;#39;&lt;/span&gt;, () =&amp;gt; {
  assert((&lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;) &lt;span style=&#34;color:#ff79c6&#34;&gt;===&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt;);
})
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So why does Jest need 30+ matcher methods?  Because they allow you to be specific in your intent, and also let Jest provide helpful error messages.  For instance, when you write a test like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; getRecord &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; () =&amp;gt; ({ id&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;fullName&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Ben McCormick&amp;#39;&lt;/span&gt;});
test(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;records have a name and an ID&amp;#39;&lt;/span&gt;, () =&amp;gt; {
    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; record &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; getRecord(&lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;);
    expect(record).toHaveProperty(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;id&amp;#39;&lt;/span&gt;);
    expect(record).toHaveProperty(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;name&amp;#39;&lt;/span&gt;);
})
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;it is obvious what the test is trying to check, and you can get detailed output like this:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;error_output.png&#34; alt=&#34;Error output from Jest&#34;&gt;&lt;/p&gt;
&lt;p&gt;You get the structure of the object as it is, the name of the property that is missing, the line number and file name where you can find the assertion, all in a concise, colorful and nicely formatted test failure message.&lt;/p&gt;
&lt;p&gt;You can categorize Jest&amp;rsquo;s matchers into 8 different categories: equality matchers, template matchers, numeric comparison matchers, contains matchers, async matchers, snapshot matchers, function matchers, and meta matchers.  I&amp;rsquo;ll go through the first 3 in this post, and cover the rest in a followup.&lt;/p&gt;
&lt;h3 id=&#34;equality-matchers&#34;&gt;Equality Matchers&lt;/h3&gt;
&lt;p&gt;Equality matchers are the workhorse matchers of any test libraries.  This is where we see whether an expression evaluates to the value we expect. This being JavaScript however, equality takes a few different forms, and Jest covers each of them, along with some syntactic shortcuts.&lt;/p&gt;
&lt;h4 id=&#34;tobe-and-toequal&#34;&gt;toBe and toEqual&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;toBe&lt;/code&gt;, as mentioned previously, is the simplest Jest matcher.  It is equivalent to a simple &lt;code&gt;===&lt;/code&gt; statement, and verifies that the expression being tested is the same reference as the expression that it is matched against.  Since it is reference based, toBe is a good fit for numbers, strings and booleans, or for checking that an object is the exact same reference as another object.  But it&amp;rsquo;s not good for comparing two separate objects.  It behaves like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;expect(&lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;).toBe(&lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt;) &lt;span style=&#34;color:#6272a4&#34;&gt;// true
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;expect(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;on&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;e&amp;#39;&lt;/span&gt;).toBe(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;one&amp;#39;&lt;/span&gt;) &lt;span style=&#34;color:#6272a4&#34;&gt;// true
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;expect(&lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;===&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;).toBe(&lt;span style=&#34;color:#ff79c6&#34;&gt;true&lt;/span&gt;) &lt;span style=&#34;color:#6272a4&#34;&gt;// true
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; oneObj &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {one&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;};
expect(oneObj).toBe(oneObj) &lt;span style=&#34;color:#6272a4&#34;&gt;// true
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;expect(oneObj).toBe({one&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;}) &lt;span style=&#34;color:#6272a4&#34;&gt;// false!
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For comparing object and array equality, it usually is better to use &lt;code&gt;toEqual&lt;/code&gt;, which does a deep property comparison:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; oneObj &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {one&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;};
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; nestedObj &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {nested&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; {one&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;}};
expect(oneObj).toEqual({one&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;}) &lt;span style=&#34;color:#6272a4&#34;&gt;// true
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;expect(nestedObj).toEqual({nested&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; {one&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;}}) &lt;span style=&#34;color:#6272a4&#34;&gt;// true
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;toEqual&lt;/code&gt; doesn&amp;rsquo;t line up to any built in JavaScript idea of equality exactly, it just does a recursive equal check. But it behaves like most people who haven&amp;rsquo;t already encountered the details of JavaScript equality would expect equality to work.  If objects share the same structure and values, they&amp;rsquo;re equal. There also is no Jest equivalent to &lt;code&gt;==&lt;/code&gt; with its odd type casting behavior, and that is ok by me.&lt;/p&gt;
&lt;h4 id=&#34;tobedefined-tobenull-and-tobeundefined&#34;&gt;toBeDefined, toBeNull and toBeUndefined&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;toBeDefined&lt;/code&gt;, &lt;code&gt;toBeNull&lt;/code&gt;, and &lt;code&gt;toBeUndefined&lt;/code&gt; are all shortcut functions.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;// same as expect(x).toBe(null)
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;expect(x).toBeNull()
&lt;span style=&#34;color:#6272a4&#34;&gt;// same as expect(typeof x).toBe(&amp;#39;undefined&amp;#39;)
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;expect(x).toBeUndefined()
&lt;span style=&#34;color:#6272a4&#34;&gt;// same as expect(typeof x).not.toBe(&amp;#39;undefined&amp;#39;)
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;expect(x).toBeDefined()
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;One thing worth pointing out here is the use of &lt;code&gt;.not&lt;/code&gt; in my example comment.
&lt;code&gt;.not&lt;/code&gt; is a utility property that you can chain to reverse the output of
any matcher.&lt;/p&gt;
&lt;h4 id=&#34;tobefalsy-and-tobetruthy&#34;&gt;toBeFalsy and toBeTruthy&lt;/h4&gt;
&lt;p&gt;These matchers essentially are shortcuts that act like &lt;code&gt;if&lt;/code&gt; and &lt;code&gt;else&lt;/code&gt; statements.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;// same as expect(!!x).toBe(true)
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;expect(x).toBeTruthy()
&lt;span style=&#34;color:#6272a4&#34;&gt;// same as expect(!!x).toBe(false)
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;expect(x).toBeFalsy()
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If you aren&amp;rsquo;t aware of the JavaScript concepts of truthiness and falsiness, the terms refer to whether a value is evaluated as true or false when evaluated in a boolean context.&lt;/p&gt;
&lt;h3 id=&#34;template-matchers&#34;&gt;Template matchers&lt;/h3&gt;
&lt;p&gt;Template matchers are matchers that don&amp;rsquo;t check for a specific value, but instead look to see if the expression is consistent with a certain pattern or shape.&lt;/p&gt;
&lt;h4 id=&#34;tomatch&#34;&gt;toMatch&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;toMatch&lt;/code&gt; is a template matcher for strings.  It accepts a regular expression that
you can use to describe the acceptable list of strings.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; id1 &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;155-60-7723&amp;#39;&lt;/span&gt;;
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; id2 &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;15-60-7723&amp;#39;&lt;/span&gt;;
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; socialSecurityNumberFormat &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;/\d{3}-\d{2}-\d{4}/&lt;/span&gt;;
expect(id1).toMatch(socialSecurityNumberFormat); &lt;span style=&#34;color:#6272a4&#34;&gt;// true
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;expect(id2).toMatch(socialSecurityNumberFormat); &lt;span style=&#34;color:#6272a4&#34;&gt;// false
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;tomatchobject-and-tohaveproperty&#34;&gt;toMatchObject and toHaveProperty&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;toMatchObject&lt;/code&gt; and &lt;code&gt;toHaveProperty&lt;/code&gt; are template matchers for objects. &lt;code&gt;toMatchObject&lt;/code&gt; works similarly to &lt;code&gt;toEqual&lt;/code&gt; and does a deep comparison on objects and arrays.  But unlike &lt;code&gt;toEqual&lt;/code&gt;, &lt;code&gt;toMatchObject&lt;/code&gt; doesn&amp;rsquo;t require an exact match, it just verifies that the expression has the same properties as the template object.  So extra properties on the expression we&amp;rsquo;re evaluating don&amp;rsquo;t matter.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; oneObj &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {one&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;, uno&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;};
expect(oneObj).toEqual({one&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;}) &lt;span style=&#34;color:#6272a4&#34;&gt;// false
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;expect(oneObj).toMatch({one&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;}) &lt;span style=&#34;color:#6272a4&#34;&gt;// true
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;toHaveProperty&lt;/code&gt; performs a similar function but doesn&amp;rsquo;t enforce the whole structure of an object.  Instead it just tests whether a single property is defined.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; oneObj &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {one&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;};
expect(oneObj).toHaveProperty(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;one&amp;#39;&lt;/span&gt;) &lt;span style=&#34;color:#6272a4&#34;&gt;// true
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;toHaveProperty&lt;/code&gt; can take a second &amp;ldquo;value&amp;rdquo; argument, at which point it acts as a more limited version of &lt;code&gt;toMatch&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; oneObj &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {one&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;};
expect(oneObj).toHaveProperty(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;one&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;) &lt;span style=&#34;color:#6272a4&#34;&gt;// true
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;expect(oneObj).toHaveProperty(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;one&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt;) &lt;span style=&#34;color:#6272a4&#34;&gt;// false
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;tohavelength&#34;&gt;toHaveLength&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;toHaveLength&lt;/code&gt; is a simple matcher for checking the length of strings, arrays and any other array-like object that has a length property.  &lt;code&gt;expect(x).toHaveLength(y)&lt;/code&gt; is just a shorthand for &lt;code&gt;expect(x.length)&lt;/code&gt; with the benefit of handling undefined values of &lt;code&gt;x&lt;/code&gt; safely.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;expect(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Hello&amp;#39;&lt;/span&gt;).toHaveLength(&lt;span style=&#34;color:#bd93f9&#34;&gt;5&lt;/span&gt;) &lt;span style=&#34;color:#6272a4&#34;&gt;// true
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;expect([&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Hello&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;From&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;The&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Other&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Side&amp;#39;&lt;/span&gt;]).toHaveLength(&lt;span style=&#34;color:#bd93f9&#34;&gt;5&lt;/span&gt;) &lt;span style=&#34;color:#6272a4&#34;&gt;// true
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;expect({length&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;5&lt;/span&gt;}).toHaveLength(&lt;span style=&#34;color:#bd93f9&#34;&gt;5&lt;/span&gt;) &lt;span style=&#34;color:#6272a4&#34;&gt;// true
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;tobeinstanceof&#34;&gt;toBeInstanceOf&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;toBeInstanceOf&lt;/code&gt; allow&amp;rsquo;s checking the &amp;ldquo;type&amp;rdquo; of an object to see if it is an instance of a class, including inherited classes.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;test(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;We can test whether an object is an instance of a class&amp;#39;&lt;/span&gt;, () =&amp;gt; {
  &lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; A{}
  &lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; B &lt;span style=&#34;color:#ff79c6&#34;&gt;extends&lt;/span&gt; A{}
  &lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; C{}

  &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; a &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; A();
  &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; b &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; B();
  &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; c &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; C();
  expect(a).toBeInstanceOf(A); &lt;span style=&#34;color:#6272a4&#34;&gt;// true
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;  expect(b).toBeInstanceOf(A); &lt;span style=&#34;color:#6272a4&#34;&gt;// true because of inheritance
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;  expect(c).not.toBeInstanceOf(A); &lt;span style=&#34;color:#6272a4&#34;&gt;// true
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;})
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;tothrow&#34;&gt;toThrow&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;toThrow&lt;/code&gt; is a bit of a different template matcher, because rather than matching a value, it matches against an exception.  &lt;code&gt;except()&lt;/code&gt; takes a function, and instead of evaluating that function, it executes the function and looks to see if an exception is thrown. If there is an exception, &lt;code&gt;toThrow&lt;/code&gt; can take a string, regex or Class and acts like either &lt;code&gt;toMatch&lt;/code&gt; or &lt;code&gt;toBeInstanceOf&lt;/code&gt; depending on what it is passed.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;test(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;We can match exceptions&amp;#39;&lt;/span&gt;, () =&amp;gt; {
  &lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; throwingFunc1 &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; () =&amp;gt; {
    &lt;span style=&#34;color:#ff79c6&#34;&gt;throw&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;error&amp;#39;&lt;/span&gt;;
  };
  &lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; SpecialError{}
  &lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; throwingFunc2 &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; () =&amp;gt; {
      &lt;span style=&#34;color:#ff79c6&#34;&gt;throw&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; SpecialError()
  };

  expect(throwingFunc1).toThrow(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;err&amp;#39;&lt;/span&gt;); &lt;span style=&#34;color:#6272a4&#34;&gt;// true
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;  expect(throwingFunc1).toThrow(&lt;span style=&#34;color:#f1fa8c&#34;&gt;/err/&lt;/span&gt;); &lt;span style=&#34;color:#6272a4&#34;&gt;// true
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;  expect(throwingFunc2).toThrow(SpecialError); &lt;span style=&#34;color:#6272a4&#34;&gt;// true
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;})
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;numeric-comparison-matchers&#34;&gt;Numeric Comparison Matchers&lt;/h3&gt;
&lt;p&gt;Numeric comparison matchers are straightforward.  They test whether a number relates correctly to another number.&lt;/p&gt;
&lt;h4 id=&#34;tobegreaterthan-tobegreaterthanorequal-tobelessthan-tobelessthanorequal&#34;&gt;toBeGreaterThan, toBeGreaterThanOrEqual, toBeLessThan, toBeLessThanOrEqual&lt;/h4&gt;
&lt;p&gt;These are exactly what they sound like.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;expect(&lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;).toBeGreaterThan(&lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;) &lt;span style=&#34;color:#6272a4&#34;&gt;// false
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;expect(&lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt;).toBeGreaterThan(&lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;) &lt;span style=&#34;color:#6272a4&#34;&gt;// true
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;expect(&lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;).toBeGreaterThanOrEqual(&lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;) &lt;span style=&#34;color:#6272a4&#34;&gt;// true
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;expect(&lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt;).toBeGreaterThanOrEqual(&lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;) &lt;span style=&#34;color:#6272a4&#34;&gt;// true
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;expect(&lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;).toBeLessThan(&lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;) &lt;span style=&#34;color:#6272a4&#34;&gt;// false
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;expect(&lt;span style=&#34;color:#bd93f9&#34;&gt;0&lt;/span&gt;).toBeLessThan(&lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;) &lt;span style=&#34;color:#6272a4&#34;&gt;// true
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;expect(&lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;).toBeLessThanOrEqual(&lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;) &lt;span style=&#34;color:#6272a4&#34;&gt;// true
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;expect(&lt;span style=&#34;color:#bd93f9&#34;&gt;0&lt;/span&gt;).toBeLessThanOrEqual(&lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;) &lt;span style=&#34;color:#6272a4&#34;&gt;// true
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;tobecloseto&#34;&gt;toBeCloseTo&lt;/h4&gt;
&lt;p&gt;This test checks whether a number is the same as another number within a set number of significant digits.  &lt;code&gt;toBeCloseTo&lt;/code&gt; takes a number and an optional second option that determines the number of significant digits, then tests whether an expression is the same as that number within that number of significant digits.  This is useful in JavaScript since &lt;a href=&#34;https://stackoverflow.com/questions/588004/is-floating-point-math-broken&#34;&gt;floating point math is not precise and 0.1 + 0.2 famously does not equal 0.3 exactly&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;test(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Floating Point Math Is Hard&amp;#39;&lt;/span&gt;, () =&amp;gt; {
  expect(&lt;span style=&#34;color:#bd93f9&#34;&gt;0.2&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;0.1&lt;/span&gt;).not.toBe(&lt;span style=&#34;color:#bd93f9&#34;&gt;0.3&lt;/span&gt;) &lt;span style=&#34;color:#6272a4&#34;&gt;//true
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;  expect(&lt;span style=&#34;color:#bd93f9&#34;&gt;0.2&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;0.1&lt;/span&gt;).toBeCloseTo(&lt;span style=&#34;color:#bd93f9&#34;&gt;0.3&lt;/span&gt;) &lt;span style=&#34;color:#6272a4&#34;&gt;//true
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;})
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;part-2-coming-soon&#34;&gt;Part 2 Coming Soon&lt;/h3&gt;
&lt;p&gt;There&amp;rsquo;s a lot to cover here, so check back soon for part 2 of this post, with contains matchers, async matchers, snapshot matchers, function matchers, meta matchers, and a few extra tricks for using matchers.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>My Favorite Interview Question</title>
      <link>https://benmccormick.org/2017/07/24/064500.html</link>
      <pubDate>Mon, 24 Jul 2017 07:45:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2017/07/24/064500.html</guid>
      <description>&lt;p&gt;I have a favorite question to ask in interviews for web developers.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“How does the internet work?  In other words, when I open a browser and enter a url then hit enter, and a website shows up on my screen what can you tell me about what is happening?”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Usually I get one of a few responses:&lt;/p&gt;
&lt;h4 id=&#34;1-the-clueless-shrug&#34;&gt;1. The clueless shrug&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;Uh….  ¯\_(ツ)_/¯&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Some people have no idea what to do with the question.  Things get awkward. This is mostly for junior positions but still isn&amp;rsquo;t the best sign.  Sometimes a few prods will get things back on track.&lt;/p&gt;
&lt;h4 id=&#34;2-the-bare-minimum&#34;&gt;2. The bare minimum&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;It is asking a server for the site and the server sends you the site.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Some people can give a very basic response, but don&amp;rsquo;t give a lot of details.  This again mostly corresponds to less experienced devs and can be fine as a starting spot with some follow-up questions.&lt;/p&gt;
&lt;h4 id=&#34;3-the-cliffnotes&#34;&gt;3. The CliffNotes&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;Your browser sends an HTTP request which gets routed through a local modem/router and gets sent to a name server for its url extension.  That name server routes the request to the correct IP address, which will resolve to some sort of web server.  That server will serve up either some static files, or run some backend code in order to generate a resource (probably an html page).  When the HTML page is returned, your browser will parse it, which will likely generate more requests, and the cycle will repeat.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Some people know how some of this works, maybe with a few hazy areas and can explain it in a reasonably straightforward way.  An explanation like this is a great start.&lt;/p&gt;
&lt;h4 id=&#34;4-the-geek-out&#34;&gt;4. The Geek-out&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;Some variation on the previous answer... followed by:&gt; Let me tell you all about my in depth knowledge of &amp;lt;HTTP_network routing_JavaScript parsing/TCP/other related topic&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Some people dive in and explode with information.&lt;/p&gt;
&lt;h3 id=&#34;so-why-is-this-a-good-interview-question-again&#34;&gt;So why is this a good interview question again?&lt;/h3&gt;
&lt;p&gt;So which answer is best?  The geek-out right?  Well&amp;hellip; its great when somebody gets there, but in my mind this question is more about the journey than the destination.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s pretty easy to make the case that this is a pretty bad interview question.  It&amp;rsquo;s not clear what the expected answer is.  When I ask it in junior dev interviews, they often don&amp;rsquo;t have much of a clue how to answer it.  And it&amp;rsquo;s not strictly answerable in full detail by pretty much anyone.  But I&amp;rsquo;d argue that those things actually end up being strengths.  I like this question for 5 reasons.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;It tests the candidate&amp;rsquo;s ability to deal with ambiguity.&lt;/strong&gt;  The question is intentionally vague and open ended.  Am I just looking for a perfunctory response like &amp;ldquo;it gets a resource from a server&amp;rdquo;?  Do I want a deep dive into how DNS works?  It&amp;rsquo;s ambiguous.  Candidates can respond to that ambiguity in one of a few ways.&lt;/p&gt;
&lt;p&gt;They can freeze because they&amp;rsquo;re afraid of saying the wrong thing.&lt;/p&gt;
&lt;p&gt;They can ask a clarifying question.&lt;/p&gt;
&lt;p&gt;They can make a guess at what I want and start going down that road, while reading my reaction to see if they&amp;rsquo;re still on track.&lt;/p&gt;
&lt;p&gt;Or they can decide they know what I want (or what they want to tell me) and shoot off like a rocket (potentially for a very long time).&lt;/p&gt;
&lt;p&gt;This is super useful information in an interview because developers deal with ambiguity all the time.  When a candidate encounters unclear requirements from a product manager, or unclear documentation from another developer, it&amp;rsquo;s good to have an idea how they&amp;rsquo;ll respond&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;It tests the breadth of a candidates knowledge.&lt;/strong&gt; - For the most part, when I interview people, I ask them questions about the role they&amp;rsquo;re applying for:  Front-End Dev, Backend Dev, QA Engineer, etc.  But this question gives a candidate the chance to show that they understand what&amp;rsquo;s happening up and down the web stack from the code they interact with the most.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;It gives the candidate a chance to explain a complex technical topic.&lt;/strong&gt; - In my mind, good communication ability is the most important skill for a developer once they&amp;rsquo;ve achieved a minimum level of technical competence.  Being able to talk about problems and solutions clearly and explain them to a variety of audiences matters, and it matters a lot.  Can the candidate summarize a complex technical topic without getting bogged down in details?  Are they communicating with me (verbally or otherwise) to make sure I&amp;rsquo;m following their explanation?  Or are they fading off into a rambling run-on explanation of a trivial detail without any big picture context?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;It forces the candidate to confront something they don’t know.&lt;/strong&gt; - The internet is a perfect example of the Isaac Newton quote about &lt;a href=&#34;https://en.wikipedia.org/wiki/Standing_on_the_shoulders_of_giants&#34;&gt;standing on the shoulders of giants&lt;/a&gt;.  It is the culmination of 50+ years of research and work on networked computer systems.  No candidate I interview for a web development position is going to understand every detail of how it works, because you can always go a layer deeper in the stack or afield into crazier edge case behavior.  So at some point in questioning (possibly very early), this question exhausts every candidate&amp;rsquo;s knowledge.  The question is how do they react?  Some candidates start guessing at things.  Some admit they don&amp;rsquo;t know.  Some try to skirt around areas they don&amp;rsquo;t feel confident in and work at avoiding any questions where they would have to admit they don&amp;rsquo;t know something.  And some will actually ask me how part of the system works.  This again is helpful because &amp;ldquo;not knowing the answer&amp;rdquo; is such a common experience in real world web dev.  It&amp;rsquo;s great to have some clues to how a candidate handles that.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;It gives the candidate an opportunity to show off what they know.&lt;/strong&gt;  I&amp;rsquo;ve gotten some amazing answers to this question.  It turns out some candidates actually know a lot about networking and HTTP/TCP/nameservers.  Some can give detailed answers about browsers and how they parse resources and display the DOM.  Maybe they just know a lot of random trivia about URLs and DNS.  Regardless, this is a chance to show off and prove that they&amp;rsquo;ve delved deep into something.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;To be clear, I don&amp;rsquo;t think every interview question should be like this one.  Most should probably directly relate to the work the candidate is doing, be clearly comparable in an objective way candidate to candidate, and not risk sending the interview down a 10 minute rabbit hole.  But this one is my favorite, and I think there&amp;rsquo;s a place for questions that show how a candidate might handle some real world lack of structure.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Feel free to hit me up on Twitter at &lt;a href=&#34;https://twitter.com/_benmccormick&#34;&gt;@_benmccormick&lt;/a&gt; to tell me your favorite interview question.  I&amp;rsquo;ll retweet them.&lt;/p&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;There is of course a limit to how much any interview is going to teach you about how somebody will behave in a future job situation.  We&amp;rsquo;re all chasing breadcrumbs here.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>Ten Things A Serious JavaScript Developer Should Learn</title>
      <link>https://benmccormick.org/2017/07/18/230000.html</link>
      <pubDate>Wed, 19 Jul 2017 00:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2017/07/19/230000.html</guid>
      <description>&lt;p&gt;There’s been an interesting Reddit thread circling my corner of the internet for the last week or so. It started with a question:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I’m inviting pure opinion here, but what’s your list of ten things that everyone looking for a good javascript role should know and understand. Personally, I’m in a role where what I know is adequate, but I want to be somewhere better; somewhere that has some flippin standards. I’m learning outside of work requirements at the moment, but there is so much to learn out there.
The objective is to do good work in a good place.
Narrow it down to your ten for me, or for you..&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;From &lt;a href=&#34;https://www.reddit.com/r/javascript/comments/6mlc9d/what_10_things_should_a_serious_javascript/&#34;&gt;“What 10 Things Should a Serious Javascript Developer Know Right Now?”&lt;/a&gt;&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt; &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I think this is a great question if you take it seriously, because when you think about it critically, it exposes all of the things JavaScript don’t really &lt;strong&gt;need&lt;/strong&gt; to know. Can you contribute productively as a mid-level JavaScript developer without knowing anything about &lt;a href=&#34;https://github.com/prettier/prettier&#34;&gt;Prettier&lt;/a&gt;, &lt;a href=&#34;https://www.typescriptlang.org/&#34;&gt;Typescript&lt;/a&gt; or &lt;a href=&#34;https://facebook.github.io/react/&#34;&gt;React&lt;/a&gt;? Sure! Can you contribute productively if you’re writing and testing your JavaScript using &lt;em&gt;&amp;lt;awful uncool code editor that you the reader can’t stand&amp;gt;&lt;/em&gt;? Definitely. So here’s my take on answering the question.&lt;/p&gt;
&lt;h2 id=&#34;assumptions&#34;&gt;Assumptions&lt;/h2&gt;
&lt;p&gt;I’m making the following assumptions about the question&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;I’m assuming the audience is a developer who has some level of professional programming experience and some existing JavaScript experience, and that they are primarily interested in “code skill” answers. Thus I’ll exclude things like communication ability, experience with version control, professional conduct, or basic coding ability that are very important to success in a JavaScript development environment but are out of the scope of this question.&lt;/li&gt;
&lt;li&gt;I’m optimizing for “what specific pre-existing knowledge will make the most difference between success and failure for a new hire in a mid-level JavaScript role”.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Pre-existing&lt;/strong&gt; means that these are things that somebody is expected to know before taking the job. Learning the details of a company’s technology stack, style guide and engineering philosophy are all important, but you shouldn’t be expected to know them in advance, and in many cases doing so is impossible.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Specific knowledge&lt;/strong&gt; means that these are things that you can learn with some effort and study. They should not be broad categories like “security”, “design”, or “server-side development”. They should be things you know or know how to do, not things you “have experience with”. And they should be specific enough that somebody can feel comfortable saying they understand the topic or don’t. Most of the things I list below are &lt;em&gt;topics&lt;/em&gt;, but I try to lay out a specific set of things that you would need to know to understand it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The most difference between success and failure&lt;/strong&gt; means that these are the things that are really going to make a difference in how effective you are at understanding and completing the work assigned to you. There are many such things, and their importance will vary situationally, so this is just my educated take on a generalists list.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;When I say **mid-level**, I&#39;m picturing hiring for a role that pays well but is not the most senior person on the team.  This would be a developer who would be expected to complete tasks with minimal help and oversight but wouldn&#39;t necessarily be planning the architecture of everything right off the bat.  To be clear this list is not a set of things that you need to go to get paid to write JavaScript.  It is more along the lines of &#34;next steps&#34; for junior devs.  Its also not a step function where you need to know all of these at once to get to the next level.  These are just things that may limit you if you don&#39;t have them.
&lt;p&gt;I&amp;rsquo;m taking the liberty to assume that &lt;strong&gt;JavaScript role&lt;/strong&gt; implies using JavaScript in some sort of client/UI environment (Browser, React Native, Cordova, Electron, etc).  This list would be at least a bit different for a Node.js server-side role, and somebody else will have to write that post.
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;h2 id=&#34;thelist&#34;&gt;The List&lt;/h2&gt;
&lt;h4 id=&#34;1.youshouldknowthecorelanguage&#34;&gt;&lt;strong&gt;1. You should know the core language&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;JavaScript is not a very complicated language at its core. It can seem difficult to learn because of all of the noise around it. Browser APIs, Library APIs, jQuery, React, TypeScript, the many npm packages out there, etc all can make the language syntax space seem huge. And this isn’t helped by the fact that the language has evolved over time so you’ll see many different ways to do a single task spread out over the internet. But the core language and standard libraries are actually pretty small compared to languages like Python and Java that have more features and larger standard libraries. Eventually you’ll need the ecosystem. But knowing the core language features that are implemented in most browsers is a great start.&lt;/p&gt;
&lt;p&gt;This means you should know about basic language features like if/else, error handling with throw/try/catch, array manipulation with push/map/reduce/filter, and string manipulation methods like replace/slice/split. You should also know about how JavaScript handles things like truthiness and falsiness&lt;a id=&#34;fnref:1&#34; class=&#34;footnote&#34; title=&#34;see footnote&#34; href=&#34;#fn:1&#34;&gt;[1]&lt;/a&gt;, how to work with JSON data with the JSON object methods, and how variable scope works in JavaScript. These days its also becoming more and more important to have at least a basic familiarity with the more important language features that were added in ES6 like Promises, modules, classes, template literals, generators and destructuring. Even if you choose not to use those features, being able to see and understand them will help you learn faster from others.&lt;/p&gt;
&lt;p&gt;This list is mostly unordered, but this comes first because learning everything else becomes a lot harder without this knowledge, mostly because it becomes difficult to learn from other people’s code since you won’t understand what it is doing. If you’re starting from a weak base here I’d recommend finding a good book on the core language like &lt;a href=&#34;http://amzn.to/2uD4R1Y&#34;&gt;Eloquent JavaScript&lt;/a&gt;&lt;a id=&#34;fnref:2&#34; class=&#34;footnote&#34; title=&#34;see footnote&#34; href=&#34;#fn:2&#34;&gt;[2]&lt;/a&gt; and digging in. If you’ve been using JavaScript in an older code base or haven’t used it in a while and want to catch up, you can see &lt;a href=&#34;https://benmccormick.org/2017/07/10/how-to-follow-the-javascript-roadmap/&#34;&gt;my post on keeping up with new language features&lt;/a&gt;.&lt;/p&gt;
&lt;h4 id=&#34;2.youshouldunderstandasynccode&#34;&gt;2. You should understand async code&lt;/h4&gt;
&lt;p&gt;One of the biggest leaps for new JavaScript developers, even those who are experienced with other languages is the amount of asynchronous code found in idiomatic JavaScript. Asynchronous (async) code is code that is scheduled to run at a later time after some event, delay or response. It can appear a bunch of different ways in JavaScript code, and it’s important to be able to interpret them.&lt;/p&gt;
&lt;p&gt;This means learning about &lt;a href=&#34;https://benmccormick.org/2015/12/30/es6-patterns-converting-callbacks-to-promises/&#34;&gt;callbacks and promises&lt;/a&gt; at least. You should also learn about the JavaScript &lt;a href=&#34;http://blog.carbonfive.com/2013/10/27/the-javascript-event-loop-explained/&#34;&gt;event loop&lt;/a&gt; and how it works Ideally some of the standard APIs that use them like &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Talk:DOM/window.setTimeout&#34;&gt;setTimeout&lt;/a&gt; and &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch&#34;&gt;fetch&lt;/a&gt;. If you’re ambitious you can learn about newer async syntax and library implementations like &lt;a href=&#34;https://ponyfoo.com/articles/understanding-javascript-async-await&#34;&gt;async-await&lt;/a&gt; or &lt;a href=&#34;https://github.com/Reactive-Extensions/RxJS&#34;&gt;RxJS&lt;/a&gt; But the most important thing is to spend time using and writing async code so that you get an intuitive understanding of how it works.&lt;/p&gt;
&lt;h4 id=&#34;3.youshouldgetcomfortablewithatleastonesetofdevelopertools&#34;&gt;&lt;strong&gt;3. You should get comfortable with at least one set of developer tools&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;When developing JavaScript, its important to be able to debug problems and understand how existing systems work. JavaScript has a fantastic ecosystem of developer tools for diagnosing bugs and examining application code. For the most part they’re bundled with browsers (though some IDEs like VS Code and WebStorm have their own debuggers). Learning how to use these tools well will turbocharge your JS dev skills. If you can’t use them though, it will make everything much harder.&lt;/p&gt;
&lt;p&gt;Competence in this means comfort with at least the JavaScript debugger panel of a browser’s devtools. You should be able to set and use breakpoints, use watch mode and the console to test for the value of expressions, and understand the stack traces. But its also good to get comfortable using the elements panel to understand and manipulate the DOM, and the network panel to debug network requests.&lt;/p&gt;
&lt;h4 id=&#34;4.youshouldbeproficientwithjavascriptfunctions&#34;&gt;4. You should be proficient with JavaScript functions&lt;/h4&gt;
&lt;p&gt;Functions are the core of the JavaScript language. You should be able to use them fluently. That means understanding function scope, closures, how &lt;code&gt;this&lt;/code&gt; works, and the difference between normal functions and arrow functions. It also means knowing about how to process arrays with function using methods like map, filter, and reduce. A good resource for “thinking in functions” is &lt;a href=&#34;https://leanpub.com/javascriptallongesix/read&#34;&gt;JavaScript Allonge&lt;/a&gt; by Reginald Braithwaite.&lt;/p&gt;
&lt;h4 id=&#34;5.youshouldbecomfortablewithbasicdesigntasks&#34;&gt;5. You should be comfortable with basic design tasks&lt;/h4&gt;
&lt;p&gt;No matter how well you learn JavaScript, you’ll be limited career-wise if you can’t manage basic design tasks. This might not seem inherently true; after all isn’t that what professional designers are for? But the truth is that unless you’re a purely server-side developer (excluded by our assumptions above), there will be times when you’re asked to fill in a visual gap that a designer doesn’t have time for, or there will be ambiguities in a designers spec that aren’t worth a meeting. And learning the basics of design will help you communicate better with designers and product managers about technical constraints and design requirements.&lt;/p&gt;
&lt;p&gt;When I talk design, I mean both the basics of implementing a visual design with HTML and CSS&lt;a id=&#34;fnref:3&#34; class=&#34;footnote&#34; title=&#34;see footnote&#34; href=&#34;#fn:3&#34;&gt;[3]&lt;/a&gt;, and enough of an understanding of design basics to create a simple UI that looks ok and isn’t confusing. That last requirement is harder than you’d think. Design is hard and mostly orthogonal to the set of skills most folks pick up while learning to code. For learning design theory, I’d recommend finding a simple resource on visual design first like &lt;a href=&#34;http://amzn.to/2uz3vEG&#34;&gt;White Space is Not Your Enemy&lt;/a&gt;, and ideally supplementing that with a more UX focused resource like &lt;a href=&#34;http://amzn.to/2uvUrR7&#34;&gt;Don’t Make Me Think&lt;/a&gt;. The practical side of HTML/CSS is easiest to pick up with experience. If you’re using devtools you can see what other people are doing with CSS and tweak and explore using the elements panel. And there are lots of good online resources for learning about CSS and HTML syntax like &lt;a href=&#34;https://developer.mozilla.org/en-US/&#34;&gt;MDN&lt;/a&gt; for API info or &lt;a href=&#34;https://css-tricks.com/&#34;&gt;CSS-Tricks&lt;/a&gt; for ideas, tutorials and keeping up with new stuff.&lt;/p&gt;
&lt;h4 id=&#34;6.youshouldhaveabasicunderstandingofnetworkingandhttp-basedapis&#34;&gt;6. You should have a basic understanding of networking and HTTP-based APIs&lt;/h4&gt;
&lt;p&gt;Because we’re assuming that this job involves using JavaScript in a browser or other client context, you should be able to understand the basics of networking. You should know what a client and server is. You should be able to explain a rough approximation of what happens when somebody enters a URL into the browser&lt;a id=&#34;fnref:4&#34; class=&#34;footnote&#34; title=&#34;see footnote&#34; href=&#34;#fn:4&#34;&gt;[4]&lt;/a&gt;. There’s a bunch of vocabulary thats good to know here. You should know what an HTTP request is and ideally know the conventions of what GET/PUT/POST/DELETE imply. It will help you to have a working definition of what REST is and what AJAX is. It’s good to get experience working with some HTTP based APIs, either at work or playing around with an API like &lt;a href=&#34;https://dev.twitter.com/rest/public&#34;&gt;Twitter&lt;/a&gt; or &lt;a href=&#34;https://developer.github.com/v3/&#34;&gt;Github&lt;/a&gt;. You should also get familiar with at least one way to make HTTP requests in JavaScript (XMLHttpRequest, fetch, jQuery’s ajax methods).&lt;/p&gt;
&lt;h4 id=&#34;7.youshouldbecomfortablewithnode.jsbasedtooling&#34;&gt;7. You should be comfortable with Node.js based tooling&lt;/h4&gt;
&lt;p&gt;One of the biggest shifts in the last 5 years in the JavaScript world has been the explosive growth and consolidation of tools to help build JavaScript applications. Tools like &lt;a href=&#34;http://eslint.org/&#34;&gt;eslint&lt;/a&gt;, &lt;a href=&#34;http://babeljs.io/&#34;&gt;Babel&lt;/a&gt;, &lt;a href=&#34;https://www.typescriptlang.org/&#34;&gt;Typescript&lt;/a&gt;, and &lt;a href=&#34;https://webpack.js.org/&#34;&gt;Webpack&lt;/a&gt; are essential to many teams workflows. While you don’t necessarily have to be experienced writing applications for Node.js, it is important that you be able to use those tools. That means knowing how to install Node and use npm to install and update packages. It also means getting comfortable with build tools like Webpack, Rollup or Ember CLI and knowing how to use them. Reasonable people can differ on how many tools and libraries you should be using, or what the right ones to use are, but having a basic familiarity with how the Node ecosystem works has become essential.&lt;/p&gt;
&lt;h4 id=&#34;8.youshouldknowhowtouseaframeworktostructureamoderatelysizedprogram&#34;&gt;8. You should know how to use a framework to structure a moderately sized program&lt;/h4&gt;
&lt;p&gt;A critical requirement for a developer who is expected to complete work with minimum supervision or hand-holding is the ability to structure their code in a maintainable way. That means having an understanding of (or helping define) the overall architecture of the system, and then writing code that fits into it. It also means being able to identify and help solve situations where the current architecture or code base norms causes problems. I put this in terms of frameworks because pretty much all medium to large JavaScript programs are using some sort of framework, whether it is an “official” framework like React, Angular, and Ember or a collection of helper files and functions cobbled together by a development team over time. For learning purposes, the popular official frameworks will usually be better to learn, since the knowledge can translate elsewhere, the purposes behind the structure are documented on the internet, and at least some sense of best practice architecture should be embedded in the code. To check this box I think it would be best to get experience with at least 2 frameworks/architectures, since it is difficult to tell which decisions a Framework makes are specific to its architecture and constraints without something to compare it with.&lt;/p&gt;
&lt;p&gt;This is probably the most controversial item on this list, since I know a lot of folks believe it’s better to learn architecture ideas outside the constraints of a framework. My stance here is that frameworks are practical: they’re most likely to translate to an actual employment background and it’s easy to find practical explanations of how they solve architecture problems.&lt;/p&gt;
&lt;h4 id=&#34;9.youshouldknowthebasicsofjavascriptprogramperformance&#34;&gt;9. You should know the basics of JavaScript program performance&lt;/h4&gt;
&lt;p&gt;Like design, performance is a deep well of things you can learn. But knowing the basics is important and can go a long ways. For performance “the basics” is more about process than knowledge. You need to learn how to debug slow processes and understand where the problems are coming from. For browser environments in particular there are some baseline things to understand. You’ll want to be able to tell the difference between code that is running slowly due to parsing slowness, runtime slowness, and network latency. It’s important to learn how to keep a UI responsive and not block rendering with other calculations. And it’s great to understand how to cache data and avoid making too many requests to the server.&lt;/p&gt;
&lt;p&gt;This is also an area where learning more about Computer Science theory can be beneficial. Studying data structures and algorithms can help give you good intuitions on how to handle data, and learning about Big O notation gives you a language for discussing performance tradeoffs. This is the type of background knowledge that pays off in occasional subtle ways though, not something that is always obvious applicable in the moment.&lt;/p&gt;
&lt;h4 id=&#34;10.youshouldhaveaprocessforlearningnewthings&#34;&gt;10. You should have a process for learning new things&lt;/h4&gt;
&lt;p&gt;JavaScript development has changed a lot over the last 10 years, and there’s no reason to think it won’t continue to evolve over the next 10. There are also a lot of different technologies that fall under the umbrella of JavaScript, more than any one person can keep in their head. So it’s important to be able to keep up with the new technologies as they come along, and also learn about new technologies quickly when you need them. Ideally this means having at least one place where you can follow news about new JavaScript innovation. Could be Twitter, a set of blogs, newsletters or an aggregator site like Reddit or Hacker News. If you’re looking for an easy place to start, I’d recommend the &lt;a href=&#34;http://javascriptweekly.com/&#34;&gt;JavaScript Weekly mailing list&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You also need to get comfortable finding information about specific technologies, either to learn to use them or troubleshoot problems. These resources will likely be more varied, but it’s important to learn to &lt;a href=&#34;https://xkcd.com/627/&#34;&gt;Google well&lt;/a&gt;, and also helpful to get familiar with &lt;a href=&#34;http://stackoverflow.com/&#34;&gt;Stack Overflow&lt;/a&gt; or some other resource for getting help when you have specific questions or problems.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Do you have a different list? Feel free to post it and then link in the comments!&lt;/p&gt;
&lt;div class=&#34;footnotes&#34;&gt;&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;If you don’t learn all the pitfalls here, at least learn that there are pitfalls. &lt;a class=&#34;reversefootnote&#34; title=&#34;return to article&#34; href=&#34;#fnref:1&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;Disclosure: Some of these book links are affiliate links &lt;a class=&#34;reversefootnote&#34; title=&#34;return to article&#34; href=&#34;#fnref:2&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;Or SASS/LESS/CSS in JS/whatever &lt;a class=&#34;reversefootnote&#34; title=&#34;return to article&#34; href=&#34;#fnref:3&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;This can be explained at several levels, but its good to at least know that a request is sent from the users computer to a server somewhere, and that server returns resources like HTML, CSS, JS, and image files.  &lt;a class=&#34;reversefootnote&#34; title=&#34;return to article&#34; href=&#34;#fnref:4&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>How to follow the JavaScript roadmap</title>
      <link>https://benmccormick.org/2017/07/10/070000.html</link>
      <pubDate>Mon, 10 Jul 2017 08:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2017/07/10/070000.html</guid>
      <description>&lt;p&gt;It can be difficult to keep up with all the things going on in web development, especially since the JavaScript language itself has been changing over the last several years.  After several years of relative stability&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;, the ECMAScript spec (&lt;a href=&#34;https://benmccormick.org/2015/09/14/es5-es6-es2016-es-next-whats-going-on-with-javascript-versioning/&#34;&gt;ECMAScript is the specification for the JavaScript language&lt;/a&gt;) has changed quite a bit over the last 3 years, with more changes on the way.  In this post I wanted to highlight a few of the resources I can recommend for keeping up with the language changes.&lt;/p&gt;
&lt;h3 id=&#34;learning-es6es2015&#34;&gt;Learning ES6/ES2015&lt;/h3&gt;
&lt;p&gt;If you haven&amp;rsquo;t paid attention to any features that aren&amp;rsquo;t ready in all browsers yet, or you&amp;rsquo;re getting back to JavaScript development after being away for a while, you probably could use a resource to catchup on the ES6 JavaScript release from 2015.  ES6 is now &lt;a href=&#34;https://kangax.github.io/compat-table/es6/&#34;&gt;almost completely&lt;/a&gt; implemented in the latest versions of all major browsers, so if you&amp;rsquo;ve been ignoring it due to compatibility concerns, now is the time to learn.  Fortunately there are a lot of great resources for learning about ES6.  My favorite quick reference is the &lt;a href=&#34;https://babeljs.io/learn-es2015/&#34;&gt;Learn ES2015 page&lt;/a&gt; from &lt;a href=&#34;https://babeljs.io/&#34;&gt;Babel&lt;/a&gt;.  It&amp;rsquo;s a short, example filled page with explanations of all the major features of the language update. If you want something meatier, there have been several resources created by JS experts.  &lt;a href=&#34;http://amzn.to/2tVcwaW&#34;&gt;Understanding ECMAScript 6&lt;/a&gt; by &lt;a href=&#34;https://www.nczonline.net/about/&#34;&gt;Nicholas Zakas&lt;/a&gt; and &lt;a href=&#34;http://exploringjs.com/es6.html&#34;&gt;Exploring ES6&lt;/a&gt; by &lt;a href=&#34;http://2ality.com/&#34;&gt;Axel Rauschmayer&lt;/a&gt; are books that go through the new features in detail.  If you prefer video tutorials, &lt;a href=&#34;http://wesbos.com/&#34;&gt;Wes Bos&lt;/a&gt; has a &lt;a href=&#34;https://es6.io/&#34;&gt;whole video course on ES6&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;keeping-up-with-new-features&#34;&gt;Keeping up with new features&lt;/h3&gt;
&lt;p&gt;Things haven&amp;rsquo;t been changing as fast since the ES6 release.  The first 2 &amp;ldquo;annual releases&amp;rdquo; of the ECMAScript spec contained only a &lt;a href=&#34;http://2ality.com/2016/01/ecmascript-2016.html&#34;&gt;combined&lt;/a&gt; &lt;a href=&#34;http://2ality.com/2016/02/ecmascript-2017.html&#34;&gt;8 features&lt;/a&gt;. but there are still a lot of new features working their way through the ECMAScript pipeline.  If you want to get a quick overview of the features being considered for future releases, the best place to look is the &lt;a href=&#34;https://github.com/tc39/proposals&#34;&gt;TC39 proposals repo on Github&lt;/a&gt;.  TC39 is the organization that guides the future of the ECMAScript spec.  Proposals go through a 4 stage process, where stage 1 can best be understood as &amp;ldquo;ideas&amp;rdquo;, and stage 4 is &amp;ldquo;confirmed for the next ECMAScript release&amp;rdquo;.  &lt;a href=&#34;https://ponyfoo.com/contributors/ponyfoo&#34;&gt;Nicolás Bevacqua&lt;/a&gt; put up a &lt;a href=&#34;https://ponyfoo.com/articles/tc39-ecmascript-proposals-future-of-javascript&#34;&gt;good post&lt;/a&gt; last week describing this process in depth, as well as giving a brief description of the more advanced proposals in the queue. If you&amp;rsquo;re interested in keeping up with new proposals but want somebody to walk you through them, I recommend subscribing to Axel Rauschmayer&amp;rsquo;s &lt;a href=&#34;http://2ality.com/&#34;&gt;2ality&lt;/a&gt; blog.  In addition to writing the ES6 book mentioned above, he regularly writes blog posts highlighting new proposals with detailed explanations of the feature implementation and motivation.&lt;/p&gt;
&lt;h3 id=&#34;testing-new-features&#34;&gt;Testing new features&lt;/h3&gt;
&lt;p&gt;Almost all of the higher stage proposals on the TC39 list have been implemented by &lt;a href=&#34;https://babeljs.io/&#34;&gt;Babel&lt;/a&gt; and you can try them out in the Babel &lt;a href=&#34;https://babeljs.io/repl/#?babili=false&amp;amp;evaluate=true&amp;amp;lineWrap=false&amp;amp;presets=es2015%2Creact%2Cstage-2&amp;amp;targets=&amp;amp;browsers=&amp;amp;builtIns=false&amp;amp;debug=false&amp;amp;code_lz=Q&#34;&gt;REPL&lt;/a&gt; or by setting up a small project that loads in Babel.&lt;/p&gt;
&lt;h3 id=&#34;keeping-up-with-the-conversation&#34;&gt;Keeping up with the conversation&lt;/h3&gt;
&lt;p&gt;If you&amp;rsquo;re a twitter user, probably the easiest way to keep up with language evolution is to follow the people who are shaping and teaching the new language features.  Some twitter follow recommendations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://twitter.com/wycats&#34;&gt;Yehuda Katz&lt;/a&gt; - TC39 member, Ember core developer&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://twitter.com/rauschma&#34;&gt;Axel Rauschmayer&lt;/a&gt; - JS blogger and trainer&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://twitter.com/wesbos&#34;&gt;Wes Bos&lt;/a&gt; - JS blogger and trainer&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://twitter.com/sebmarkbage&#34;&gt;Sebastian Markbåge&lt;/a&gt; - TC39 member, React core developer&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://twitter.com/left_pad&#34;&gt;Henry Zhu&lt;/a&gt; - Babel maintainer&lt;/li&gt;
&lt;/ul&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;From the release of the ECMAScript 5 spec to the ES6/ECMAScript2015 spec, the language wasn&amp;rsquo;t exactly stable in practice because browser implementations didn&amp;rsquo;t always move quickly, and there were still many incompatibilities.  But standard language syntax stayed stable for quite a while, which allowed the browser ecosystem to iron out some of those kinks prior to the adoption of ES6.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>Adding RSS, Atom, and JSON Feed to Gatsby</title>
      <link>https://benmccormick.org/2017/06/03/205500.html</link>
      <pubDate>Sat, 03 Jun 2017 21:55:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2017/06/04/205500.html</guid>
      <description>&lt;p&gt;For the last few months, this blog has been written in &lt;a href=&#34;https://github.com/gatsbyjs/gatsby&#34;&gt;Gatsby&lt;/a&gt;, a static site generator for JavaScript.  One of the first problems I had to solve when migrating the blog was how to maintain my RSS feed, since Gatsby doesn&amp;rsquo;t have any built in concept of an RSS feed.  This issue came up again this week as I decided to implement the new &lt;a href=&#34;https://jsonfeed.org/&#34;&gt;JSON Feed&lt;/a&gt; spec and give folks an additional option for subscribing to this blog.  Fortunately this turns out to be a pretty easy problem to solve because of the excellent npm module &lt;a href=&#34;https://github.com/jpmonette/feed&#34;&gt;feed&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;feed&lt;/em&gt; is an npm module that takes a bunch of information about a blog and its posts, and normalizes them into various syndication feed format.  Here&amp;rsquo;s what setting up a feed option looks like for this blog:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; fs &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; require(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;fs&amp;#39;&lt;/span&gt;);
&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; Feed &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; require(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;feed&amp;#39;&lt;/span&gt;);
&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; filter &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; require(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;lodash/filter&amp;#39;&lt;/span&gt;);
&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; sortBy &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; require(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;lodash/sortBy&amp;#39;&lt;/span&gt;);
&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; forEach &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; require(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;lodash/forEach&amp;#39;&lt;/span&gt;);
&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; get &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; require(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;lodash/get&amp;#39;&lt;/span&gt;);
&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; moment &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; require(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;moment&amp;#39;&lt;/span&gt;);
&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; markdownIt &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; require(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;markdown-it&amp;#39;&lt;/span&gt;);
&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; frontmatter &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; require(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;front-matter&amp;#39;&lt;/span&gt;);


&lt;span style=&#34;color:#6272a4&#34;&gt;//markdownIt is a markdown parser that takes my raw md files and
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;//translates them into HTML that we can use in the feed
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; md &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; markdownIt({
  html&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;true&lt;/span&gt;,
  linkify&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;true&lt;/span&gt;,
  typographer&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;true&lt;/span&gt;,
});


&lt;span style=&#34;color:#6272a4&#34;&gt;// getPageContent is a function to help us grab the html content from a post path
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; getPageContent &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; page =&amp;gt; {
  &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; file &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; fs.readFileSync(__dirname &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;/pages/&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; page.requirePath, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;utf-8&amp;#39;&lt;/span&gt;);
  &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; body &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; md.render(frontmatter(file).body);
  &lt;span style=&#34;color:#6272a4&#34;&gt;// handle local links
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; body.replace(&lt;span style=&#34;color:#f1fa8c&#34;&gt;/src=&amp;#34;\//g&lt;/span&gt;, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;src=&amp;#34;http://benmccormick.org/&amp;#39;&lt;/span&gt;);
};

&lt;span style=&#34;color:#6272a4&#34;&gt;// build feed is our main function to build a `Feed` object which we
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;// can then serialize into various formats
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; buildFeed &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; pages =&amp;gt; {
  &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; feed &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; Feed({
    title&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;benmccormick.org&amp;#39;&lt;/span&gt;,
    description&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;A blog by Ben McCormick&amp;#39;&lt;/span&gt;,
    link&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;http://benmccormick.org&amp;#39;&lt;/span&gt;,
    id&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;http://benmccormick.org&amp;#39;&lt;/span&gt;,
    copyright&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;All rights reserved 2016, Ben McCormick&amp;#39;&lt;/span&gt;,
    feedLinks&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; {
      atom&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;http://benmccormick.org/atom.xml&amp;#39;&lt;/span&gt;,
      json&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;http://benmccormick.org/feed.json&amp;#39;&lt;/span&gt;,
    },
    author&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; {
      name&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Ben McCormick&amp;#39;&lt;/span&gt;,
      email&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;ben@benmccormick.org&amp;#39;&lt;/span&gt;
    }
  });
  &lt;span style=&#34;color:#6272a4&#34;&gt;// ignore pages (non posts)
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;  pages &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; filter(pages, p =&amp;gt; ( &lt;span style=&#34;color:#ff79c6&#34;&gt;!&lt;/span&gt;(get(p, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;data.layout&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;page&amp;#39;&lt;/span&gt;) &lt;span style=&#34;color:#ff79c6&#34;&gt;===&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;page&amp;#39;&lt;/span&gt;)));
  &lt;span style=&#34;color:#6272a4&#34;&gt;// we only want the last 10 articles to show up in the feed
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;  pages &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; sortBy(pages, page =&amp;gt; get(page, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;data.date&amp;#39;&lt;/span&gt;));
  pages &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; pages.reverse();
  pages &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; pages.slice(&lt;span style=&#34;color:#bd93f9&#34;&gt;0&lt;/span&gt;, &lt;span style=&#34;color:#bd93f9&#34;&gt;10&lt;/span&gt;);

  forEach(pages, page =&amp;gt; feed.addItem({
    title&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; page.data.title,
    id&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;https://benmccormick.org&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; page.path,
    link&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;https://benmccormick.org&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; page.path,
    date&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; moment(page.data.date).toDate(),
    content&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; getPageContent(page),
    author&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; [
      {
        name&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Ben McCormick&amp;#39;&lt;/span&gt;,
        email&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;ben@benmccormick.org&amp;#39;&lt;/span&gt;,
        link&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;https://benmccormick.org&amp;#39;&lt;/span&gt;
      }
    ]
  }));
  feed.addContributor({
    name&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Ben McCormick&amp;#39;&lt;/span&gt;,
    email&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;ben@benmccormick.org&amp;#39;&lt;/span&gt;,
    link&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;https://benmccormick.org&amp;#39;&lt;/span&gt;
  });
  &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; feed;
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now we have a &lt;code&gt;buildFeed&lt;/code&gt; method that takes a list of pages and generates a feed object.  Then we can use the feed object we&amp;rsquo;ve created to actually build write some files.  We&amp;rsquo;ll trigger that in the &lt;code&gt;postBuild&lt;/code&gt; callback of &lt;code&gt;gatsby-node&lt;/code&gt;.  Here was my first version to support RSS and Atom:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;
&lt;span style=&#34;color:#6272a4&#34;&gt;//mkDir and mkFile are just light wrappers around node&amp;#39;s file system APIs
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; createRSSFolder &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; () =&amp;gt; mkDir(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;/public/rss/&amp;#39;&lt;/span&gt;);
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; generateAtomFeed &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; (feed) =&amp;gt; mkFile(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;/public/atom.xml&amp;#39;&lt;/span&gt;, feed.atom1());
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; generateRSS &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; (feed) =&amp;gt; mkFile(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;/public/rss/index.xml&amp;#39;&lt;/span&gt;, feed.rss2());

exports.postBuild &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; pages =&amp;gt; {
  &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; feed &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; buildFeed(pages);
  createRSSFolder();
  generateAtomFeed(feed);
  generateRSS(feed);
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Prior to this week, &lt;code&gt;feed&lt;/code&gt; didn&amp;rsquo;t support JSON Feed, so I had stopped here.  But because JSON Feed is super simple to implement (its just JSON!), I decided to try to add it to &lt;code&gt;feed&lt;/code&gt; this week.  It turned out it was as simple as adding a single function that looks like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;json1() {
   &lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; { options, items } &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;
   &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; feed &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {
     version&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;https://jsonfeed.org/version/1&amp;#39;&lt;/span&gt;,
     title&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; options.title,
   };

   &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (options.link) {
     feed.home_page_url &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; options.link;
   }

   &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (options.feedLinks &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; options.feedLinks.json) {
     feed.feed_url &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; options.feedLinks.json;
   }

   &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (options.description) {
     feed.description &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; options.description;
   }


   &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (options.image) {
     feed.icon &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; options.image;
   }

   &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (options.author) {
     feed.author &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {};
     &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (options.author.name) {
         feed.author.name &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; options.author.name;
     }
     &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (options.author.link) {
         feed.author.url &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; options.author.link;
     }
   }
   feed.items &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; items.map(item =&amp;gt; {
     &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; feedItem &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {
       id&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; item.id,
       &lt;span style=&#34;color:#6272a4&#34;&gt;// json_feed distinguishes between html and text content
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;       &lt;span style=&#34;color:#6272a4&#34;&gt;// but since we only take a single type, we&amp;#39;ll assume HTML
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;       html_content&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; item.content,
     }
     &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (item.link) {
       feedItem.url &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; item.link;
     }
     &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt;(item.title) {
       feedItem.title &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; item.title;
     }
     &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (item.description) {
       feedItem.summary &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; item.description;
     }

     &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (item.image) {
       feedItem.image &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; item.image
     }

     &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (item.date) {
       feedItem.date_modified &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.ISODateString(item.date);
     }
     &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (item.published) {
       feedItem.date_published &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.ISODateString(item.published);
     }

     &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (item.author) {
       &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; author &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; item.author;
       &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (author &lt;span style=&#34;color:#ff79c6&#34;&gt;instanceof&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;Array&lt;/span&gt;) {
         &lt;span style=&#34;color:#6272a4&#34;&gt;// json feed only supports 1 author per post
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;         author &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; author[&lt;span style=&#34;color:#bd93f9&#34;&gt;0&lt;/span&gt;];
       }
       feedItem.author &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {};
       &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (author.name) {
           feedItem.author.name &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; author.name;
       }
       &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (author.link) {
           feedItem.author.url &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; author.link;
       }
     }
     &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; feedItem;
   });

   &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; JSON.stringify(feed, &lt;span style=&#34;color:#ff79c6&#34;&gt;null&lt;/span&gt;, &lt;span style=&#34;color:#bd93f9&#34;&gt;4&lt;/span&gt;);
 }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;My &lt;a href=&#34;https://github.com/jpmonette/feed/pull/56/files&#34;&gt;pull request&lt;/a&gt; was accepted, so feed v1.1.0 now supports JSON feed and my final code to add &lt;a href=&#34;http://benmccormick.org/rss/&#34;&gt;rss&lt;/a&gt;, &lt;a href=&#34;http://benmccormick.org/atom.xml&#34;&gt;atom&lt;/a&gt;, and &lt;a href=&#34;http://benmccormick.org/feed.json&#34;&gt;json&lt;/a&gt; feed to this site looks like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; fs &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; require(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;fs&amp;#39;&lt;/span&gt;);
&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; Feed &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; require(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;feed&amp;#39;&lt;/span&gt;);
&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; filter &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; require(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;lodash/filter&amp;#39;&lt;/span&gt;);
&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; sortBy &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; require(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;lodash/sortBy&amp;#39;&lt;/span&gt;);
&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; forEach &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; require(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;lodash/forEach&amp;#39;&lt;/span&gt;);
&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; get &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; require(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;lodash/get&amp;#39;&lt;/span&gt;);
&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; moment &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; require(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;moment&amp;#39;&lt;/span&gt;);
&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; markdownIt &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; require(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;markdown-it&amp;#39;&lt;/span&gt;);
&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; frontmatter &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; require(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;front-matter&amp;#39;&lt;/span&gt;);
&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; {mkDir, mkFile} &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; require(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;./utils/file_system&amp;#39;&lt;/span&gt;);


&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; md &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; markdownIt({
 html&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;true&lt;/span&gt;,
 linkify&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;true&lt;/span&gt;,
 typographer&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;true&lt;/span&gt;,
});

&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; extractMarkdownContent &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; file =&amp;gt; {
 &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; body &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; md.render(frontmatter(file).body);
 &lt;span style=&#34;color:#6272a4&#34;&gt;// handle local links
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; body.replace(&lt;span style=&#34;color:#f1fa8c&#34;&gt;/src=&amp;#34;\//g&lt;/span&gt;, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;src=&amp;#34;http://benmccormick.org/&amp;#39;&lt;/span&gt;);

};

&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; getPageContent &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; page =&amp;gt; {
 &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; file &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; fs.readFileSync(__dirname &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;/pages/&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; page.requirePath, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;utf-8&amp;#39;&lt;/span&gt;);
 &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; extractMarkdownContent(file);
};

&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; buildFeed &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; pages =&amp;gt; {
 &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; feed &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; Feed({
   title&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;benmccormick.org&amp;#39;&lt;/span&gt;,
   description&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;A blog by Ben McCormick&amp;#39;&lt;/span&gt;,
   link&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;http://benmccormick.org&amp;#39;&lt;/span&gt;,
   id&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;http://benmccormick.org&amp;#39;&lt;/span&gt;,
   copyright&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;All rights reserved 2016, Ben McCormick&amp;#39;&lt;/span&gt;,
   feedLinks&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; {
     atom&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;http://benmccormick.org/atom.xml&amp;#39;&lt;/span&gt;,
     json&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;http://benmccormick.org/feed.json&amp;#39;&lt;/span&gt;,
   },
   author&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; {
     name&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Ben McCormick&amp;#39;&lt;/span&gt;,
     email&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;ben@benmccormick.org&amp;#39;&lt;/span&gt;
   }
 });
 &lt;span style=&#34;color:#6272a4&#34;&gt;// ignore pages (non posts)
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt; pages &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; filter(pages, p =&amp;gt; ( &lt;span style=&#34;color:#ff79c6&#34;&gt;!&lt;/span&gt;(get(p, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;data.layout&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;page&amp;#39;&lt;/span&gt;) &lt;span style=&#34;color:#ff79c6&#34;&gt;===&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;page&amp;#39;&lt;/span&gt;)));
 &lt;span style=&#34;color:#6272a4&#34;&gt;// we only want the last 10 articles to show up in the feed
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt; pages &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; sortBy(pages, page =&amp;gt; get(page, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;data.date&amp;#39;&lt;/span&gt;));
 pages &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; pages.reverse();
 pages &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; pages.slice(&lt;span style=&#34;color:#bd93f9&#34;&gt;0&lt;/span&gt;, &lt;span style=&#34;color:#bd93f9&#34;&gt;10&lt;/span&gt;);

 forEach(pages, page =&amp;gt; feed.addItem({
   title&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; page.data.title,
   id&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;https://benmccormick.org&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; page.path,
   link&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;https://benmccormick.org&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; page.path,
   date&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; moment(page.data.date).toDate(),
   content&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; getPageContent(page),
   author&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; [
     {
       name&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Ben McCormick&amp;#39;&lt;/span&gt;,
       email&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;ben@benmccormick.org&amp;#39;&lt;/span&gt;,
       link&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;https://benmccormick.org&amp;#39;&lt;/span&gt;
     }
   ]
 }));
 feed.addContributor({
   name&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Ben McCormick&amp;#39;&lt;/span&gt;,
   email&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;ben@benmccormick.org&amp;#39;&lt;/span&gt;,
   link&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;https://benmccormick.org&amp;#39;&lt;/span&gt;
 });
 &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; feed;
};

&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; createRSSFolder &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; () =&amp;gt; mkDir(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;/public/rss/&amp;#39;&lt;/span&gt;);
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; generateAtomFeed &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; (feed) =&amp;gt; mkFile(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;/public/atom.xml&amp;#39;&lt;/span&gt;, feed.atom1());
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; generateRSS &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; (feed) =&amp;gt; mkFile(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;/public/rss/index.xml&amp;#39;&lt;/span&gt;, feed.rss2());
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; generateJSONFeed &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; (feed) =&amp;gt; mkFile(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;/public/feed.json&amp;#39;&lt;/span&gt;, feed.json1());

exports.postBuild &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; pages =&amp;gt; {
  &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; feed &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; buildFeed(pages);
  createRSSFolder();
  generateAtomFeed(feed);
  generateRSS(feed);
  generateJSONFeed(feed);
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;more-resources&#34;&gt;More Resources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;You can see the whole spec for &lt;a href=&#34;https://jsonfeed.org/&#34;&gt;JSON Feed&lt;/a&gt; on their &lt;a href=&#34;https://jsonfeed.org/&#34;&gt;site&lt;/a&gt;.  It really is remarkably simple.  They also have a list of implementations and example sites.&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Atom Productivity Tips</title>
      <link>https://benmccormick.org/2017/05/29/222000.html</link>
      <pubDate>Mon, 29 May 2017 23:20:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2017/05/30/222000.html</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://atom.io&#34;&gt;Atom&lt;/a&gt; is a modern hackable text editor.  I&amp;rsquo;ve been using it as my primary editor for a year and a half, and have picked up some tips along the way that I thought were worth sharing.  These tips assume that you have at least a passing familiarity with Atom: they&amp;rsquo;re the things that I&amp;rsquo;ve picked up over time that have made me more productive.&lt;/p&gt;
&lt;h4 id=&#34;1-there-is-more-to-the-fuzzy-finder-than-meets-the-eye&#34;&gt;1. There is more to the Fuzzy Finder than meets the eye&lt;/h4&gt;
&lt;p&gt;Fuzzy finders have been a key feature on modern editors since TextMate first popularized the ⌘T command&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; for searching through project files.  ⌘T (or ⌘P) still works great in Atom, but what you may not know is that Atom provides 2 other versions of the command. ⌘B searches only among currently open files.  ⇧⌘B searches only among files that are &amp;ldquo;dirty&amp;rdquo; according to git&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;.  Both of those options are built in.  You can also find other uses for the fuzzy-finder if you start exploring plugins, including &lt;a href=&#34;https://atom.io/packages/atom-fuzzy-grep&#34;&gt;atom-fuzzy-grep&lt;/a&gt;, a plugin that lets you use the fuzzy-finder interface to search file contents using grep, &lt;a href=&#34;https://benmccormick.org/2016/04/30/ack-tips/&#34;&gt;ack&lt;/a&gt;, ag, or ripgrep.&lt;/p&gt;
&lt;h4 id=&#34;2-atom-is-a-great-vim-replacement&#34;&gt;2. Atom is a great Vim replacement&lt;/h4&gt;
&lt;p&gt;If you&amp;rsquo;ve been following this blog for a while, you know I&amp;rsquo;ve written a lot about &lt;a href=&#34;https://benmccormick.org/learning-vim-in-2014/&#34;&gt;Vim&lt;/a&gt;.  I still love the &lt;a href=&#34;https://benmccormick.org/2014/07/16/learning-vim-in-2014-vim-as-art/&#34;&gt;philosophy of Vim&lt;/a&gt;, and think that the text editing &lt;a href=&#34;https://benmccormick.org/2014/07/02/learning-vim-in-2014-vim-as-language/&#34;&gt;language&lt;/a&gt; it implements is the best way to edit code quickly.  But Atom&amp;rsquo;s &lt;a href=&#34;https://atom.io/packages/vim-mode-plus&#34;&gt;vim-mode-plus&lt;/a&gt; is the best vi implementation I&amp;rsquo;ve seen outside of Vim, and unlike other editors, you don&amp;rsquo;t need to get frustrated with a halfway approach to Vi-keybindings, since you can make pretty much everything work in a vim-like way.  That&amp;rsquo;s because:&lt;/p&gt;
&lt;h4 id=&#34;3-atoms-keybindings-are-powerful-and-flexible&#34;&gt;3. Atom&amp;rsquo;s keybindings are powerful and flexible&lt;/h4&gt;
&lt;p&gt;Any command exposed by the core editor or a plugin in Atom can be bound to a keyboard shortcut.  None of the default commands are hard-coded, and the editor provides powerful contexts for controlling what keys have lead to what action when.  That means if I want to use &lt;code&gt;ctrl-j/k/l/h&lt;/code&gt; to control my navigation between split panes, but also use &lt;code&gt;ctrl-j/k&lt;/code&gt; to move up and down in the autocomplete widget, I can just add these lines to my &lt;code&gt;keymap.cson&lt;/code&gt; file&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-coffeescript&#34; data-lang=&#34;coffeescript&#34;&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;atom-text-editor, body&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;
  &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;ctrl-k&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;window:focus-pane-above&amp;#39;&lt;/span&gt;
  &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;ctrl-j&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;window:focus-pane-below&amp;#39;&lt;/span&gt;
  &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;ctrl-h&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;window:focus-pane-on-left&amp;#39;&lt;/span&gt;
  &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;ctrl-l&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;window:focus-pane-on-right&amp;#39;&lt;/span&gt;

&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;body atom-text-editor.autocomplete-active&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;
  &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;ctrl-k&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;autocomplete-plus:move-up&amp;#39;&lt;/span&gt;
  &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;ctrl-j&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;autocomplete-plus:move-down&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Different commands are triggered in different context.  You can also take advantage of this with vim-mode to have &amp;ldquo;normal mode only&amp;rdquo; keyboard shortcuts like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-coffeescript&#34; data-lang=&#34;coffeescript&#34;&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;atom-text-editor.vim-mode-plus.normal-mode&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;
  &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;] b&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;pane:show-next-item&amp;#39;&lt;/span&gt;
  &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;[ b&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;pane:show-previous-item&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That implements a behavior I&amp;rsquo;d missed from Vim&amp;rsquo;s &lt;a href=&#34;https://github.com/tpope/vim-unimpaired&#34;&gt;unimpaired plugin&lt;/a&gt; of moving between open files with &lt;code&gt;[b&lt;/code&gt; and &lt;code&gt;]b&lt;/code&gt;.&lt;/p&gt;
&lt;h4 id=&#34;4-make-sure-to-sync-your-settings&#34;&gt;4. Make sure to sync your settings&lt;/h4&gt;
&lt;p&gt;One area where Atom is less ideal than Vim is setting portability.  It doesn&amp;rsquo;t have a single file where all configuration is stored, or a nice settings folder that can be synced.  Instead settings are intermingled with other data in a &lt;code&gt;~/.atom&lt;/code&gt; folder, a fact that is obscured by the editor&amp;rsquo;s UI, which attempts to put a nice UI in front of all of these setting files and steer you away from editing them directly or caring about where they&amp;rsquo;re stored.  Which works great until you need to move your config to a new machine or sync between 2 machines.&lt;/p&gt;
&lt;p&gt;Fortunately, there&amp;rsquo;s a great plugin &lt;a href=&#34;https://github.com/atom-community/sync-settings&#34;&gt;sync-settings&lt;/a&gt; that makes this simple.  It does require setting up a gist to serve as your repo, but after that the process is painless and allows you to continue on unaware of the implementation details behind settings.&lt;/p&gt;
&lt;h4 id=&#34;5-check-timecop-and-clean-up-plugins-that-youre-not-using&#34;&gt;5. Check Timecop and clean up plugins that you&amp;rsquo;re not using&lt;/h4&gt;
&lt;p&gt;Atom is built on web technologies.  This is both the best and worst thing about Atom.  It leads to its greatest strengths: hackability, a focus on UX early on since they didn&amp;rsquo;t have to build a whole UI engine from scratch, and quick iteration.  But it also has very real tradeoffs, the biggest of which are battery life and startup performance&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;.  There&amp;rsquo;s not much to be done about the battery life drain; Atom is based on Chromium, and Chromium is a battery hog.  It is simply a tradeoff to understand when choosing an editor.  But startup performance is often greatly influenced by the packages that you choose to use.  Fortunately Atom includes a simple tool for tracking this called Timecop.&lt;/p&gt;
&lt;p&gt;You can find Timecop in the command palette (⇧⌘P by default).  When you run it, Timecop displays a report of all of your packages and themes and how they contribute to startup time.  It will look something like this:&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;screenshot of timecop&#34; src=&#34;timecop.png&#34;
class=&#34;full-width&#34;&gt;&lt;/p&gt;
&lt;p&gt;I wouldn&amp;rsquo;t recommend obsessing too much over timecop.  For most packages the benefit you receive is going to significantly outweigh any startup burden.  But if your editor starts to feel sluggish, this is a great first step to figuring out if there&amp;rsquo;s anything you can drop to make an impact.&lt;/p&gt;
&lt;h4 id=&#34;6-the-ui-is-just-html-and-css-and-that-means-you-can-edit-it&#34;&gt;6. The UI is just HTML and CSS, and that means you can edit it&lt;/h4&gt;
&lt;p&gt;Everything you see in an Atom UI is an HTML element, with classes that you can use to select and style them. This fact is mostly relevant when creating themes, but you can also use it to make one-off UI adjustments.  For instance, when I edit Markdown files, the &lt;a href=&#34;https://github.com/sindresorhus/atom-editorconfig&#34;&gt;editorconfig&lt;/a&gt; plugin I have installed warns me about a possible conflict with another atom package. The warning shows up as a small colored mouse icon in the status bar.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;screenshot of editorconfig mouse icon in the status bar&#34; src=&#34;editor-mouse.png&#34;
class=&#34;full-width&#34;&gt;&lt;/p&gt;
&lt;p&gt;I find this warning distracting.  I know what its there for and have decided I don&amp;rsquo;t care about it, but I can&amp;rsquo;t dismiss it normally.  So instead I can take advantage of Atom&amp;rsquo;s flexibility to just get rid of it. All I need to do is open up devtools (⇧⌘I) and find the class.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;editor-mouse-devtools.png&#34; alt=&#34;screenshot of editorconfig mouse icon in the status bar with devtools open&#34;&gt;&lt;/p&gt;
&lt;p&gt;Then we can edit our styles.less file.  Atom will open it for you if you click the &lt;em&gt;your stylesheet&lt;/em&gt; link at the top of the Settings&amp;gt;Themes page.  My edit to remove the mouse icon looks like this:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-less&#34; data-lang=&#34;less&#34;&gt;.aec-icon-mouse {
  display: none;
}
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;more-resources&#34;&gt;More Resources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;a href=&#34;https://atom.io/docs&#34;&gt;atom documentation&lt;/a&gt; is really great, and worth diving into if you want to go deeper into Atom&lt;/li&gt;
&lt;li&gt;If you&amp;rsquo;re interested in learning more about keyboard driven text editing, check out &lt;a href=&#34;https://benmccormick.org/learning-vim-in-2014/&#34;&gt;my series on Vim&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;I&amp;rsquo;m using MacOS default keyboard shortcuts for this post.  Windows and Linux shortcuts are usually similar with &lt;code&gt;ctrl&lt;/code&gt; often swapped for &lt;code&gt;⌘&lt;/code&gt;.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;Dirty files are files that have been edited and not yet added to the index or committed.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;I&amp;rsquo;ve definitely seen post-startup perf issues at points as well, but I suspect that those are implementation problems that will continue to improve as the editor matures and the underlying Chromium platform continues to push on performance.  This may be naive.&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>Mariana Syntax Theme For Atom</title>
      <link>https://benmccormick.org/2017/05/27/230500.html</link>
      <pubDate>Sun, 28 May 2017 00:05:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2017/05/28/230500.html</guid>
      <description>&lt;p&gt;Sometimes the best thing to do is steal somebody else&amp;rsquo;s good idea. I&amp;rsquo;ve been using &lt;a href=&#34;https://atom.io&#34;&gt;Atom&lt;/a&gt; as my primary text editor for a year and a half now, but I still occasionally play with other editors and keep up with their updates.  There are a crazy number of good cross platform editors these days, and they all have a bunch of good ideas that get shared and remixed across each other. This week Sublime Text came out with a new release &lt;a href=&#34;https://www.sublimetext.com/3dev&#34;&gt;Dev Build 3132&lt;/a&gt; that included 3 new color schemes.  One of them was Mariana, which I believe is a variation on the also great &lt;a href=&#34;http://labs.voronianski.com/oceanic-next-color-scheme/&#34;&gt;Oceanic Next&lt;/a&gt;, with possibly some influences from my previous favorite dark theme &lt;a href=&#34;https://github.com/chriskempson/tomorrow-theme&#34;&gt;Tommorrow Night Eighties&lt;/a&gt; &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.  It stood out to me right away.&lt;/p&gt;
&lt;blockquote class=&#34;twitter-tweet&#34; data-lang=&#34;en&#34;&gt;&lt;p lang=&#34;en&#34; dir=&#34;ltr&#34;&gt;The Mariana syntax theme that shipped in the new Sublime Text is really nice &lt;a href=&#34;https://t.co/xbmjBTNoWY&#34;&gt;pic.twitter.com/xbmjBTNoWY&lt;/a&gt;&lt;/p&gt;&amp;mdash; Ben McCormick (@_benmccormick) &lt;a href=&#34;https://twitter.com/_benmccormick/status/868160533345841152&#34;&gt;May 26, 2017&lt;/a&gt;&lt;/blockquote&gt;
&lt;p&gt;Since I&amp;rsquo;m no longer using Sublime Text, I decided to port the theme to Atom.  I built on the work of the great &lt;a href=&#34;https://github.com/atom-material/atom-material-syntax&#34;&gt;atom-material-syntax&lt;/a&gt; package to build out a new theme.  It turns out to be surprisingly easy to build a color scheme in Atom.  Fork an existing theme, change some colors and the details in package.json, delete a bunch of git tags &lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;, and then run &lt;code&gt;apm deploy minor&lt;/code&gt;, and you&amp;rsquo;re in business.&lt;/p&gt;
&lt;p&gt;You can now download &lt;a href=&#34;https://atom.io/themes/mariana-syntax&#34;&gt;mariana-syntax&lt;/a&gt; in Atom.  This was a quick port.  I&amp;rsquo;ll be working to optimize it for the languages I use (JS, Python, CSS/Less, HTML and Markdown) over the next few weeks.  I would love to see pull requests for other languages or for anything that I&amp;rsquo;ve missed so far.  I look forward to this just getting better and better. &lt;strong&gt;Update:&lt;/strong&gt; Version 0.2.0 has shipped with optimized syntax for JavaScript, Python, CSS, JSON and Markdown.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;screenshot of mariana-syntax&#34; src=&#34;mariana-screenshot.png&#34;
class=&#34;full-width&#34;&gt;&lt;/p&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;To be clear, I&amp;rsquo;m not sure how great of an influence this was.  The scheme definitely bears a strong resemblance to both of those color schemes, and the release notes credit both authors as inspiration for the 3 new syntax-themes without naming specific schemes.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;This Stack Overflow article was helpful &lt;a href=&#34;https://stackoverflow.com/a/15755041/1424361&#34;&gt;https://stackoverflow.com/a/15755041/1424361&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>Building Normal Distribution Charts Using Highcharts</title>
      <link>https://benmccormick.org/2017/05/11/213000.html</link>
      <pubDate>Thu, 11 May 2017 22:30:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2017/05/12/213000.html</guid>
      <description>&lt;p&gt;This week I got to have a little fun remembering some High School math, and using one of my favorite libraries: &lt;a href=&#34;https://www.highcharts.com/&#34;&gt;Highcharts&lt;/a&gt;.  Highcharts is a commercial JavaScript data-viz library, and it makes most standard charts and graphs a breeze to implement.  I was using it to plot a normal distribution in order to display a 95% confidence interval.  It&amp;rsquo;s a pretty straightforward problem, but its a nice example of a practical use of Highcharts, and comes with a little stats math that many of us may have learned and forgotten.&lt;/p&gt;
&lt;h3 id=&#34;the-problem&#34;&gt;The Problem&lt;/h3&gt;
&lt;p&gt;The goal was to display a &lt;a href=&#34;https://en.wikipedia.org/wiki/Normal_distribution&#34;&gt;normal distribution&lt;/a&gt; to represent a 95% confidence interval, given the upper and lower bounds of the confidence interval.  A normal distribution is the classic bell curve, where the area under any section of the graph represents the probability that the true value of the measure being tracked is within that range.  These curves are usually represented something like this:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;confidence-interval.png&#34; alt=&#34;Normal Distribution image&#34;&gt;&lt;/p&gt;
&lt;p&gt;The x axis of the curve represents the range of values, while the y axis is a function of x that shows the relative probability for different areas.  Data sets that are normally distributed conform to the above bell curve and the &lt;a href=&#34;https://en.wikipedia.org/wiki/68%E2%80%9395%E2%80%9399.7_rule&#34;&gt;68-95-99.7 rule&lt;/a&gt;. There&amp;rsquo;s a 68% chance that the true value is within 1 standard deviation of the middle of the curve (the mean), a 95% chance that the true value is within 2 standard deviations, and a 99.7% chance that the true value is within 3 standard deviations.&lt;/p&gt;
&lt;h3 id=&#34;step-1-generating-a-dataset&#34;&gt;Step 1: Generating a Dataset&lt;/h3&gt;
&lt;p&gt;Highcharts operates by plotting a set of data points, not by handling equations directly.  So our first step is computing a set of data points to plot.  We can find the equation for calculating a normal distribution&amp;rsquo;s probability density on &lt;a href=&#34;https://en.wikipedia.org/wiki/Normal_distribution&#34;&gt;Wikipedia&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;equation.png&#34; alt=&#34;Normal Distribution equation&#34;&gt;&lt;/p&gt;
&lt;p&gt;Yep, we get to play with an equation that has both π and e in it.  I hope this feels sufficiently like a high school math class now.  But we can actually choose to drop the left side of the equation.  It is the &lt;a href=&#34;https://en.wikipedia.org/wiki/Normalizing_constant&#34;&gt;normalization constant&lt;/a&gt; for the equation: it ensures that the total area under the curve equals 1, but doesn&amp;rsquo;t change the shape of the curve.  Since we&amp;rsquo;re simply displaying the shape of the graph and care primarily about showing the range along the x axis, we can ignore it and instead use this function:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; normalY &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; (x, mean, stdDev) =&amp;gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;Math&lt;/span&gt;.exp((&lt;span style=&#34;color:#ff79c6&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#bd93f9&#34;&gt;0.5&lt;/span&gt;) &lt;span style=&#34;color:#ff79c6&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;Math&lt;/span&gt;.pow((x &lt;span style=&#34;color:#ff79c6&#34;&gt;-&lt;/span&gt; mean) &lt;span style=&#34;color:#ff79c6&#34;&gt;/&lt;/span&gt; stdDev, &lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt;));
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That&amp;rsquo;s a good start, but right now we only have an upper and lower bound value for a 95% confidence interval.  So before we can apply the equation, we need to find a mean, a standard deviation, and a set of x values to run the formula against.  The mean and standard deviation are fairly straightforward, and we can use lodash to generate a set of points.  For the sake of this example, we&amp;rsquo;ll plan on generating 100 points ranging from +/- 5 standard deviations from the mean, which should allow us to see all meaningful parts of the distribution, and still have a bit of padding.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; getMean &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; (lowerBound, upperBound) =&amp;gt; (upperBound &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; lowerBound) &lt;span style=&#34;color:#ff79c6&#34;&gt;/&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt;;

&lt;span style=&#34;color:#6272a4&#34;&gt;// distance between mean and each bound of a 95% confidence interval
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;// is 2 stdDeviation, so distance between the bounds is 4
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; getStdDeviation &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; (lowerBound, upperBound) =&amp;gt; (upperBound &lt;span style=&#34;color:#ff79c6&#34;&gt;-&lt;/span&gt; lowerBound) &lt;span style=&#34;color:#ff79c6&#34;&gt;/&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;4&lt;/span&gt;;


&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; generatePoints &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; (lowerBound, upperBound) =&amp;gt; {
  &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; stdDev &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; getStdDeviation(lowerBound, upperBound);
  &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; min &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; lowerBound &lt;span style=&#34;color:#ff79c6&#34;&gt;-&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;*&lt;/span&gt; stdDev;
  &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; max &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; upperBound &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;*&lt;/span&gt; stdDev;
  &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; unit &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; max &lt;span style=&#34;color:#ff79c6&#34;&gt;-&lt;/span&gt; min &lt;span style=&#34;color:#ff79c6&#34;&gt;/&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;100&lt;/span&gt;;
  &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; _.range(min, max, unit);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now that we have the x axis locations for the points, we can generate a whole data series.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; mean &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; getMean(lowerBound, upperBound);
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; stdDev &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; getStdDeviation(lowerBound, upperBound);
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; points &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; generatePoints(lowerBound, upperBound);


&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; seriesData &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; points.map(x =&amp;gt; ({ x, y&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; normalY(x, mean, stdDev)}));
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;step-2-creating-the-chart&#34;&gt;Step 2: Creating the Chart&lt;/h3&gt;
&lt;p&gt;Now we have what we need to generate a chart!  Given the data, It&amp;rsquo;s easy to make a simple normal distribution curve with highcharts.  All we need to do is create a &lt;code&gt;&amp;lt;div id=&amp;quot;container&amp;quot;&amp;gt;&lt;/code&gt; element and then run this JavaScript:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;Highcharts.chart(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;container&amp;#39;&lt;/span&gt;, {
    chart&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; {
        type&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;area&amp;#39;&lt;/span&gt;
    },
    series&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; [{
        data&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; seriesData,
    }],
});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Which produces the following graph:&lt;/p&gt;
&lt;iframe width=&#34;100%&#34; height=&#34;400&#34; src=&#34;//jsfiddle.net/ben336/8bgm1m18/embedded/result,js/&#34;
allowfullscreen=&#34;allowfullscreen&#34; frameborder=&#34;0&#34;&gt;&lt;/iframe&gt;
&lt;p&gt;Thats a good start, but contains a lot of &amp;ldquo;stuff&amp;rdquo; that Highcharts provides by default that we don&amp;rsquo;t necessarily want for our normal distribution illustration.  Let&amp;rsquo;s cut the title, legend, y-axis, and tooltips/mouse action.  To do that we need a bit more configuration:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;Highcharts.chart(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;container&amp;#39;&lt;/span&gt;, {
    chart&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; {
        type&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;area&amp;#39;&lt;/span&gt;,
        height&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;300&lt;/span&gt;,
    },
    title&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; {
        text&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;
    },
    yAxis&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; {
      labels&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; {
        enabled&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;false&lt;/span&gt;,   
      },
      gridLineWidth&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;0&lt;/span&gt;,
      title&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;
    },
    tooltip&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; {
       enabled&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;false&lt;/span&gt;,
    },
    legend&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; {
      enabled&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;false&lt;/span&gt;,
    },
    series&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; [{
        data&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; seriesData,
    }],
    plotOptions&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; {
      area&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; {
        enableMouseTracking&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;false&lt;/span&gt;,
      }
    }
});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;iframe width=&#34;100%&#34; height=&#34;400&#34; src=&#34;//jsfiddle.net/ben336/w7165m2u/embedded/result,js/&#34; allowfullscreen=&#34;allowfullscreen&#34; frameborder=&#34;0&#34;&gt;&lt;/iframe&gt;
&lt;p&gt;This is pretty great, but we still want to show our confidence interval like the wikipedia image at the top.  Ideally we&amp;rsquo;d only be filling in the areas within the 95% curve.  Thats pretty easy to do with Highcharts.  We can use &lt;em&gt;zones&lt;/em&gt;, Highcharts way of applying different styles to different sections of the chart.  We want our zones to apply to the x axis, and we&amp;rsquo;ll define 3 zones: 0 to the lower bound, lower bound to the upper bound, and everything else.  In Highcharts that looks like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;{
  plotOptions&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; {
    area&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; {
      zones&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; [{
        &lt;span style=&#34;color:#6272a4&#34;&gt;//fillColor gets the inside of the graph, color would change the lines
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;        fillColor&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;white&amp;#39;&lt;/span&gt;,
        &lt;span style=&#34;color:#6272a4&#34;&gt;// everything below this value has this style applied to it
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;        value&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; lowerBound,
      },{
        value&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; upperBound,
      },{
        fillColor&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;white&amp;#39;&lt;/span&gt;,
      }]
    },
  },
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We also want to show a 95% label on the graph like the image at the start.  There are multiple ways to do that in Highcharts, but for this simple case we&amp;rsquo;ll just abuse the title attribute and move it down into the middle of the chart:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;{
    title&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; {
        text&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;95%&amp;#39;&lt;/span&gt;,
        y&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;200&lt;/span&gt;,
    },
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;iframe width=&#34;100%&#34; height=&#34;400&#34; src=&#34;//jsfiddle.net/ben336/81kb997x/embedded/result,js/&#34; allowfullscreen=&#34;allowfullscreen&#34; frameborder=&#34;0&#34;&gt;&lt;/iframe&gt;
&lt;p&gt;And with that we&amp;rsquo;ve taken our original inputs and produced a dynamic illustration of a confidence interval that matches the image we started with.&lt;/p&gt;
&lt;h3 id=&#34;more-resources&#34;&gt;More Resources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Highcharts has great &lt;a href=&#34;http://api.highcharts.com/highcharts/&#34;&gt;documentation&lt;/a&gt; and you can see more &lt;a href=&#34;https://www.highcharts.com/demo&#34;&gt;demos&lt;/a&gt; on their site, both for Highcharts and their stock and map chart variants.  Note that Highcharts is not free for commercial use.  I&amp;rsquo;ve found that it is well worth the money though for any team that is going to be doing many data visualizations, especially if its using relatively standard forms of data visualizations on variable data.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If you need more freeform visualizations, &lt;a href=&#34;https://d3js.org/&#34;&gt;d3&lt;/a&gt; is a great place to look.  Here&amp;rsquo;s an example of D3 being used to draw a similar chart: &lt;a href=&#34;http://bl.ocks.org/phil-pedruco/88cb8a51cdce45f13c7e&#34;&gt;http://bl.ocks.org/phil-pedruco/88cb8a51cdce45f13c7e&lt;/a&gt;  It&amp;rsquo;s more involved than the Highcharts example, but allows for more flexibility as a result.  And unlike Highcharts, its free to use for anything.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Grading Applications On Config Portability</title>
      <link>https://benmccormick.org/2017/04/14/163000.html</link>
      <pubDate>Fri, 14 Apr 2017 17:30:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2017/04/14/163000.html</guid>
      <description>&lt;p&gt;This week I got a new laptop, and for the first time in a while I have separate work and personal computers.  One thing that this has made clear to me is that it is still non-trivial to keep settings and configurations easily up to date between 2 different PCs.&lt;/p&gt;
&lt;p&gt;In my experience there are several levels of &amp;ldquo;portability&amp;rdquo; for applications, which are easy to think of as letter grades.&lt;/p&gt;
&lt;h4 id=&#34;a---seamless&#34;&gt;A - &lt;em&gt;Seamless&lt;/em&gt;&lt;/h4&gt;
&lt;p&gt;These applications have built in mechanisms for syncing configs and or data between 2 different environments.  When something is updated on one machine, it is either immediately updated on the other, or easy to pull, without having to remember to update anything or doing any previous setup.&lt;/p&gt;
&lt;h4 id=&#34;b---easy&#34;&gt;B - &lt;em&gt;Easy&lt;/em&gt;&lt;/h4&gt;
&lt;p&gt;B grade applications are similar to seamless applications, but may have a few more potholes.  Possibly there is some involved setup required to get syncing working initially, or some small chunks of the application configuration don&amp;rsquo;t sync.&lt;/p&gt;
&lt;h4 id=&#34;c---workable&#34;&gt;C - &lt;em&gt;Workable&lt;/em&gt;&lt;/h4&gt;
&lt;p&gt;At this point we&amp;rsquo;ve moved out of the range of easy syncing solutions.  Here it may be possible to import and export settings from a file, without any automatic syncing.  Or there may be a straightforward way to automate the setup, but no declarative representation of the config state.&lt;/p&gt;
&lt;h4 id=&#34;d---hard&#34;&gt;D - &lt;em&gt;Hard&lt;/em&gt;&lt;/h4&gt;
&lt;p&gt;For some applications there is no clear way to sync or import state, but it is probably still possible through scripting if you&amp;rsquo;re willing to commit to it.&lt;/p&gt;
&lt;h4 id=&#34;f---impossible&#34;&gt;F - &lt;em&gt;Impossible&lt;/em&gt;&lt;/h4&gt;
&lt;p&gt;Some applications have proprietary settings that can&amp;rsquo;t be exported or scripted. There is no meaningful way to share settings for these programs.&lt;/p&gt;
&lt;h2 id=&#34;a-mixed-bag&#34;&gt;A mixed bag&lt;/h2&gt;
&lt;p&gt;Setting up my new laptop this week, I found that the software I use a lot was all over the map on this scale.  Here are the grades:&lt;/p&gt;
&lt;h4 id=&#34;atom---b&#34;&gt;Atom - &lt;em&gt;B&lt;/em&gt;&lt;/h4&gt;
&lt;img src=&#34;atom.jpg&#34; alt =&#34;Atom Logo&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://atom.io/&#34;&gt;Atom&lt;/a&gt; doesn&amp;rsquo;t have native syncing persay (though most configs are in a ~/.atom folder that can possibly be synced with git).  But it has a very nice &lt;a href=&#34;https://github.com/atom-community/sync-settings&#34;&gt;sync-settings&lt;/a&gt; plugin that uses gists to sync settings across multiple machines.  It loses points due to a little bit of upfront pain (when setting up a new machine you need to either create a new gist or find your old one, and you need to generate github auth keys for each instance), but gains them back with a very nice set of options to selectively restore or choose when to backup, and painless support for all of Atom&amp;rsquo;s 3rd party plugiuns&lt;/p&gt;
&lt;h4 id=&#34;sublime-text---b&#34;&gt;Sublime Text - &lt;em&gt;B+&lt;/em&gt;&lt;/h4&gt;
&lt;p&gt;&lt;img src=&#34;sublime.png&#34; alt=&#34;Sublime Logo&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.sublimetext.com/3&#34;&gt;Sublime Text&lt;/a&gt; saves all of its configurations as JSON, so its pretty easy to move them over.  It loses a few points though for making you figure out how to sync them, and a few more points for sticking user configs by default in the &lt;code&gt;~/Library/Application Support/&lt;/code&gt; directory, where it is a bit more difficult to sync using things like git and dotfiles.&lt;/p&gt;
&lt;h4 id=&#34;command-line-programs---a-&#34;&gt;Command Line programs - &lt;em&gt;A-&lt;/em&gt;&lt;/h4&gt;
&lt;div class=&#34;img-group&#34;&gt;
  &lt;image alt=&#34;Vim logo&#34; src=&#34;vim.png&#34;&gt;
  &lt;image alt=&#34;fish logo&#34; src=&#34;fish.png&#34;&gt;
&lt;/div&gt;
&lt;div class=&#34;img-group&#34;&gt;
  &lt;image alt=&#34;git logo&#34; src=&#34;git.png&#34;&gt;
&lt;/div&gt;
&lt;p&gt;Command line programs like Vim, Ack, bash/zsh/fish, and git all nail the idea of declarative configuration files that are stored in a common place.  They fall short of a pure A since they don&amp;rsquo;t provide a sync solution themselves (that would be very non-unixy), but since it is easy to set up &lt;a href=&#34;https://dotfiles.github.io/&#34;&gt;dotfile repos&lt;/a&gt; to sync and backup these settings, they qualify for a strong A-.&lt;/p&gt;
&lt;h4 id=&#34;iterm2---c&#34;&gt;iTerm2 - &lt;em&gt;C&lt;/em&gt;&lt;/h4&gt;
&lt;p&gt;&lt;img src=&#34;iterm.png&#34; alt=&#34;iterm2 Logo&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.iterm2.com/&#34;&gt;iterm2&lt;/a&gt; is probably the most popular terminal replacement on the mac.  It has tons of settings that you normally edit through a GUI menu.  It does allow you to export those settings, and import them on another machine.  So you need to have access to the original file to generate a snapshot at any given time and need a way to transfer the file(s), but otherwise this is still pretty workable.&lt;/p&gt;
&lt;h4 id=&#34;hyper---a-&#34;&gt;Hyper - &lt;em&gt;A-&lt;/em&gt;&lt;/h4&gt;
&lt;p&gt;&lt;a href=&#34;https://hyper.is/&#34;&gt;Hyper&lt;/a&gt; is a newer &lt;a href=&#34;https://electron.atom.io/&#34;&gt;Electron&lt;/a&gt;-based terminal application for OSX.  Like Sublime Text, it defaults to offering a GUI interface into text based configuration files.  Unlike Sublime Text, it stores that file and its plugin files in the users home directory where they can easily be included in a dotfile repo.&lt;/p&gt;
&lt;h4 id=&#34;macos---d-&#34;&gt;MacOS - &lt;em&gt;D-&lt;/em&gt;&lt;/h4&gt;
&lt;p&gt;&lt;img src=&#34;macos.jpg&#34; alt=&#34;macOS sierra Logo&#34;&gt;&lt;/p&gt;
&lt;p&gt;Unlike most of the applications I run on it, MacOS is extremely unfriendly to syncing configurations.  There are a few settings I want the same on all my laptops.  Touchpad scrolling should be in the &amp;ldquo;unnatural&amp;rdquo;&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; direction, keys should repeat when held, and caps log should be disabled/mapped to control.  There is a set of apps that I would always want to have installed.  There is no declarative way to configure this, or sync it across computers.  Apple&amp;rsquo;s preferred strategy seems to be having folks use time machine backups, which is great for setting up a new computer for the same purpose as an old one when it is being replaced, but unhelpful when 2 laptops are being used by the same person for different purposes.  It is possible to script the setup of a new laptop with scripts like &lt;a href=&#34;https://github.com/mathiasbynens/dotfiles/blob/master/.macos&#34;&gt;this one&lt;/a&gt; but its very involved and when you update a setting the &amp;ldquo;normal MacOS way&amp;rdquo;, its not always clear how you would add that setting to a script.  Plus a &amp;ldquo;from scratch&amp;rdquo; script won&amp;rsquo;t help keep 2 machines aligned as their configs diverge over time.&lt;/p&gt;
&lt;h4 id=&#34;cloud-services---a&#34;&gt;Cloud Services - &lt;em&gt;A&lt;/em&gt;&lt;/h4&gt;
&lt;p&gt;Unsurprisingly, the one class of software that really nails this experience is cloud software.  For services like Dropbox, Bear, Evernote, Slack, email &amp;amp; calendar clients, etc, most if not all settings and data is stored on servers somewhere else, so getting a new machine up to date and staying in sync over time is just a matter of entering a password.  There are reasons to dislike cloud services, but when moving to a new machine, they&amp;rsquo;re a thing of beauty.&lt;/p&gt;
&lt;h2 id=&#34;takeaways&#34;&gt;Takeaways&lt;/h2&gt;
&lt;p&gt;If you are going to be using 2 computers for different purposes as a developer, take the time to setup a good dotfiles repo that contains the configs for the command line programs and editors you use.  These days if you do that, pretty much everything else but the operating system will come right along.&lt;/p&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;Honestly the wording around that feature is pretty insulting.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>The Mystery Of Docker And The Disk-Eating Cow</title>
      <link>https://benmccormick.org/2017/03/28/094000.html</link>
      <pubDate>Tue, 28 Mar 2017 10:40:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2017/03/28/094000.html</guid>
      <description>&lt;p&gt;Yesterday morning I was innocently minding my own business, downloading some files, when I noticed that nearly all the disk space on my 256GB work laptop had been consumed.  This seemed rather unlikely to me, given that I&amp;rsquo;d only had the laptop for about a year and I didn&amp;rsquo;t store anything other than code and work documents on it.  Text files just don&amp;rsquo;t take up that much space most of the time.  So I decided to make a purchase I&amp;rsquo;d considered for a while, bought &lt;a href=&#34;https://daisydiskapp.com/&#34;&gt;Daisy Disk&lt;/a&gt;, and began investigating.&lt;/p&gt;
&lt;p&gt;The first thing I noticed was a huge amount of the disk space (about half) was taken up by the &lt;code&gt;~/Library/Containers&lt;/code&gt; folder. That folder contained my email history and also data on my &lt;a href=&#34;https://www.docker.com/&#34;&gt;Docker&lt;/a&gt; containers. Docker functions as a lightweight VM, and essentially holds copies of virtualized operating systems and file systems inside each docker container and image, so it made sense to me that it could be taking up a lot of space, though &amp;gt;120GB still seemed wrong for my paltry 4 containers.  So my first step was to delete all of the containers and images on my laptop.  That cleared about 20GB of space but still left my drive looking like this:&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;daisy disk showing 100+GB of docker&#34; src=&#34;daisy.png&#34;
class=&#34;full-width&#34;&gt;&lt;/p&gt;
&lt;p&gt;At this point, I was annoyed.  103.5 GB was taken up by some folder called Docker.qcow2 and Daisy Disk wouldn&amp;rsquo;t show me what was inside.  So I drilled in on the file system and immediately found out that Docker.qcow2 was not a directory like I&amp;rsquo;d assumed due to size, but a single 100+GB file.  At that point I decided to poll my teammates to see if I was the only one dealing with this:&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;daisy disk showing 100+GB of docker&#34; src=&#34;slack.png&#34;
class=&#34;full-width&#34;&gt;&lt;/p&gt;
&lt;p&gt;So between the 5 of us, we each had &amp;ldquo;cow files&amp;rdquo; taking up between 23 and 103GB of disk space. Some Googling revealed a &lt;a href=&#34;https://github.com/docker/for-mac/issues/371&#34;&gt;github thread&lt;/a&gt; that showed this is a so far unsolved issue with Docker For Mac.  Summary: qcow2 files are a format for saving disk images.  Docker For Mac&amp;rsquo;s implementation works well for writing and updating images, but doesn&amp;rsquo;t automatically free up disk space when a container or image is deleted. So as you use and delete containers over time this file gradually grows.  I have a habit of deleting and recreating containers when I&amp;rsquo;m trying to debug something, which explains why I had a much larger file than others.  There isn&amp;rsquo;t currently a true fix for this issue, but you can delete the file.  You&amp;rsquo;ll lose all your containers and images, but when you recreate them the file will be small again.  There also is supposed to be some automatic limiting of the file.  The current cap is 64GB, but there is work on making it configurable.  Unfortunately the current cap is not respected if you had previously used docker-machine to control docker on your machine, which is how my file exceeded the cap.  I&amp;rsquo;m also unclear on what happens when the file hits the cap.  I get the impression that things stop working and you need to delete everything anyway (you just avoid running out of disk space on the host machine).&lt;/p&gt;
&lt;p&gt;Fortunately it was no problem for me to delete everything, and so I was able to clear things out, at which point my disk looked a lot happier:&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;daisy disk showing 100+GB of docker&#34; src=&#34;daisy2.png&#34;
class=&#34;full-width&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;lessons-learned&#34;&gt;Lessons Learned&lt;/h3&gt;
&lt;p&gt;I had 3 takeaways from this interesting adventure.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;If you&amp;rsquo;re using Docker For Mac, keep an eye on your disk space.  If you&amp;rsquo;re able to occasionally delete and recreate your containers without data loss, consider occasionally doing that and deleting the cow file.  If you can&amp;rsquo;t do that, be careful how many containers you add and delete, and make sure you manage your disk space well.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://daisydiskapp.com/&#34;&gt;Daisy Disk&lt;/a&gt; is awesome and highly recommended.  It&amp;rsquo;s an example of a rare breed: the beautiful system utility. The visualizations it shows are both pretty and useful; it made diagnosing this issue a breeze.&lt;/li&gt;
&lt;li&gt;One more thing I learned from my coworkers slack yesterday: &lt;code&gt;ls&lt;/code&gt; takes an &lt;code&gt;-h&lt;/code&gt; argument that shows file sizes in KBs/MBs/GBs instead of all in bytes.  This is super helpful when examining large files.  Compare the 2 lists of files from my Downloads folder in the image below. The normal form is very nice for comparing 2 files side by side and seeing which one is bigger, but the second form is much more helpful when you want to get an idea of exactly how big something is, or communicate it to others.  Most of us don&amp;rsquo;t think about file sizes in terms of bytes anymore.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img alt=&#34;daisy disk showing 100+GB of docker&#34; src=&#34;downloads.png&#34;
class=&#34;full-width&#34;&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Running Jest Tests Before Each Git Commit</title>
      <link>https://benmccormick.org/2017/02/26/180000.html</link>
      <pubDate>Sun, 26 Feb 2017 19:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2017/02/26/180000.html</guid>
      <description>&lt;p&gt;My main work project makes heavy use of &lt;a href=&#34;https://facebook.github.io/jest/&#34;&gt;Jest&lt;/a&gt; to test our JavaScript code. For a while now I’ve wanted to set up a way to run tests every time I run a commit. I knew that git provides &lt;a href=&#34;https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks&#34;&gt;hooks&lt;/a&gt; that allow scripting actions to occur before or after any commit or push, and in fact we were already using a &lt;code&gt;pre-commit&lt;/code&gt; hook script to lint our code with &lt;a href=&#34;http://eslint.org/&#34;&gt;ESLint&lt;/a&gt;. But it was non-obvious how to make that work well with Jest testing. I eventually figured out a setup that worked, and the found a better way to do both the Jest and ESLint testing. Since it took me a while to work through, I thought I’d share it here and save the rest of you some time.&lt;/p&gt;
&lt;h3 id=&#34;whatdidntwork&#34;&gt;What didn’t work&lt;/h3&gt;
&lt;p&gt;A naive approach to this problem would be to set up a pre-commit hook that simply ran &lt;code&gt;jest&lt;/code&gt; to run all tests. The problem is that running our full test suite currently takes between 10 and 20 seconds to run all tests and that time is increasing as we grow our test suite. Adding that overhead to every commit would cost my team a lot of time, and would be especially inefficient since the repo contains plenty non-JavaScript code that doesn’t require tests to be run when updated.&lt;/p&gt;
&lt;p&gt;For our ESLint hook, we queried git to get a list of staged files, and then ran eslint against each one of them individually, displaying a pass/fail message. That looked something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;bash&#34;&gt;STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep &#34;js$&#34;)
if [[ &#34;$STAGED_FILES&#34; = &#34;&#34; ]]; then
    exit 0
fi
&lt;p&gt;PASS=true&lt;/p&gt;
&lt;p&gt;for FILE in $STAGED_FILES
do
eslint &amp;ndash;quiet &amp;ldquo;$FILE&amp;rdquo;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;if [[ &amp;quot;$?&amp;quot; == 0 ]]; then
    echo &amp;quot;\t\033[32mESLint Passed: $FILE\033[0m&amp;quot;
else
    echo &amp;quot;\t\033[41mESLint Failed: $FILE\033[0m&amp;quot;
    PASS=false
fi
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;done
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;This works great for ESLint, but doesn’t work out of the box for Jest, because I don’t want Jest to run the files that changed, I want them to run any tests that changed AND any tests that might have been broken because of that.&lt;/p&gt;
&lt;p&gt;Jest has a wonderful command line flag &lt;code&gt;jest --onlyChanged&lt;/code&gt;/&lt;code&gt;jest -o&lt;/code&gt; that runs only the tests related to files that have been changed according to git. It is extremely helpful since it is smart enough to read the dependency structure for the project and run all tests that might be changed from updating a source file. It also has a &lt;code&gt;--lastCommit&lt;/code&gt; option that does the same thing for files that were in the previous commit. Unfortunately, these options aren’t helpful at the point of committing, since &lt;code&gt;onlyChanged&lt;/code&gt; does not look at files that have been staged for commit, and we haven’t actually made a commit yet for &lt;code&gt;lastCommit&lt;/code&gt; to read.&lt;/p&gt;
&lt;h3 id=&#34;whatdidwork&#34;&gt;What Did Work&lt;/h3&gt;
&lt;p&gt;Fortunately Jest has a lower level command that uses the same logic as &lt;code&gt;onlyChanged&lt;/code&gt; and &lt;code&gt;lastCommit&lt;/code&gt;. &lt;code&gt;--findRelatedTests&lt;/code&gt; is a flag that tells Jest to run any tests related to the files passed to it instead of trying to run those files as tests as it would normally do.&lt;/p&gt;
&lt;p&gt;&lt;img style=&#34;display: block; margin-left: auto; margin-right: auto;&#34; title=&#34;jest-related-tests.png&#34; src=&#34;https://benmccormick.micro.blog/uploads/2022/6ca3a124f1.png&#34; alt=&#34;Jest related tests&#34; width=&#34;577&#34; height=&#34;473&#34; border=&#34;0&#34; /&gt;&lt;/p&gt;
&lt;p&gt;This is a perfect fit for a pre-commit hook. I was able to integrate it into my existing script like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;bash&#34;&gt;jest --bail --findRelatedTests $STAGED_FILES
if [[ &#34;$?&#34; == 0 ]]; then
    echo &#34;\t\033[32mJest Tests Passed\033[0m&#34;
else
    echo &#34;\t\033[41mJest Tests Failed\033[0m&#34;
    PASS=false
fi
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;$STAGED_FILES&lt;/code&gt; is re-used from the eslint portion of the script, and is just a space delimited list of files that are being committed. The &lt;code&gt;--bail&lt;/code&gt; option simply stops running tests as soon as one has failed. Including that is optional, you won’t see all the tests that have failed, but the failure will happen faster and you’ll be able to decide how to proceed, including possibly running the full test script on your own.&lt;/p&gt;
&lt;p&gt;Those lines (along with some sanity checks for the existence of Jest and error handling when PASS is set to false) are enough to get a workable commit hook going, but they’re not ideal. pre-commit hooks aren’t persisted by git, so each user has to install the hook script individually, and any updates aren’t shared automatically. Plus I’m inefficiently passing all staged files to eslint and Jest regardless of whether they’re JavaScript that those tools are actually meant to work on. My ESLint code was also written before ESLint developed robust &lt;code&gt;--fix&lt;/code&gt; capabilities, and doesn’t try to fix the errors it is capable of fixing. Finally, while this is just poor coding and not an inherent limitation of my other method, I’m using globally installed versions of Jest and ESLint instead of scoping them to my project.&lt;/p&gt;
&lt;h3 id=&#34;makingitbetter&#34;&gt;Making it better&lt;/h3&gt;
&lt;p&gt;Fortunately I’d discovered a better solution the other day while working on something else. There is an npm package for making this process easier, &lt;a href=&#34;https://github.com/okonet/lint-staged&#34;&gt;lint-staged&lt;/a&gt;. Lint staged abstracts away the boilerplate of getting the staged files, and makes it easy to run local node executables against specific sets of files. I was able to replace my whole pre-commit script and address all of the problems mentioned above with only a few lines in my package.json:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;json&#34;&gt;{
  &#34;scripts&#34;: {
    &#34;lint-staged&#34;: &#34;lint-staged&#34;,
  },
  &#34;lint-staged&#34;: {
    &#34;*.js&#34;: [
      &#34;eslint --fix&#34;,
      &#34;git add&#34;,
      &#34;jest --bail --findRelatedTests&#34;
    ]
  },
  &#34;devDependencies&#34;: {
    &#34;eslint&#34;: &#34;3.16.1&#34;,
    &#34;jest&#34;: &#34;19.0.1&#34;,
    &#34;lint-staged&#34;: &#34;3.3.1&#34;,
  },
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;lint-staged&lt;/code&gt; now handles making sure that I’m only running checks against JavaScript files, lets eslint autofix and stage any files that it can fix, and uses the local versions of jest and eslint. It also adds a nice pretty interface for the results:&lt;/p&gt;
&lt;p&gt;&lt;img style=&#34;display: block; margin-left: auto; margin-right: auto;&#34; title=&#34;lint-staged-errors.png&#34; src=&#34;https://benmccormick.micro.blog/uploads/2022/18f430077f.png&#34; alt=&#34;Lint staged errors&#34; width=&#34;597&#34; height=&#34;211&#34; border=&#34;0&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;lint-staged&lt;/code&gt; docs recommend using an npm based hooks manager like &lt;a href=&#34;https://github.com/observing/pre-commit&#34;&gt;pre-commit&lt;/a&gt; for running the scripts, but due to some quirks in my setup (node_modules is symlinked, and I sometimes want to run these commands inside a docker container), I found it easier to maintain a custom pre-commit script and just replace the previous logic with &lt;code&gt;npm run lint-staged&lt;/code&gt;. Either way, all of the actual logic is now checked into the repository and shared between all users. The only manual step is adding the call to a pre-commit hook or (if you’re using a helper lib) running npm install.&lt;/p&gt;
&lt;h3 id=&#34;moreresources&#34;&gt;More Resources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;This maybe merits a future post on its own, but if you’re interested in automating away your code style maintenance look at combining &lt;a href=&#34;https://github.com/prettier/prettier&#34;&gt;prettier&lt;/a&gt; (and possibly &lt;a href=&#34;https://github.com/not-an-aardvark/eslint-plugin-prettier&#34;&gt;eslint-plugin-prettier&lt;/a&gt;) with the pre-commit hooks from above. Prettier will guarantee that your code follows a consistent style, and because it handles maximum line lengths, is much more robust than ESLint on its own. Using its ESLint plugin within my editor and on pre-commit hooks has pretty much eliminated me manually fixing code style problems.&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Giving Context To Best Practices</title>
      <link>https://benmccormick.org/2017/02/18/183000.html</link>
      <pubDate>Sat, 18 Feb 2017 19:30:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2017/02/18/183000.html</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve noticed a frustrating trend in online discussions about web development where developers take their personal experience with a tool or practice and promote it as a universal truth.  Some of this is the nature of being human: we all see the world through our own lens.  But the best technical observations exist within a specific context.&lt;/p&gt;
&lt;p&gt;Compare&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Everybody should be writing code using static types, the extra syntax is worth it because of all the bugs it prevents.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;to&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If you&amp;rsquo;re working in a large code base with many developers, static typing is extremely useful, because the overhead from writing extra code and compiler errors is more than made up for by reducing bugs and clearly expressing intent when developers edit code they didn&amp;rsquo;t write.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The first quote presents a tradeoff and declares a universal preference for one direction in the tradeoff.  The second quote adds more details about the context in which the practice has been beneficial, and explains what about those circumstances (developers editing code they didn&amp;rsquo;t write) affects the tradeoff decision.&lt;/p&gt;
&lt;p&gt;These type of distinctions are often lost in online discussions about development best practices. I have no interest in naming and shaming, but specifically I&amp;rsquo;ve seen this in discussions around JavaScript performance, testing, frameworks vs other frameworks vs VanillaJS, responsive design, progressive enhancement, and build pipelines.  For this post, I&amp;rsquo;m going to try to lay out a list  of some of the context that I&amp;rsquo;ve found helpful to take into account when giving or interpreting best practice advice.&lt;/p&gt;
&lt;h3 id=&#34;context-to-keep-in-mind-when-discussing-and-interpreting-best-practices&#34;&gt;Context to keep in mind when discussing and interpreting best practices&lt;/h3&gt;
&lt;h4 id=&#34;beginner-vs-veteran&#34;&gt;Beginner vs Veteran&lt;/h4&gt;
&lt;p&gt;I&amp;rsquo;ll start with a distinction that folks seem better about making. Sometimes recommendations that make sense for beginners don&amp;rsquo;t work as well for more experienced developers and vice versa.  For instance it might make sense to advise a more experienced developer to use and heavily configure a build system like &lt;a href=&#34;https://webpack.github.io/&#34;&gt;Webpack&lt;/a&gt; for a new project. But beginners already have a lot to learn with each new project and might benefit from a simpler system; either a simple project without a build step, or a &amp;ldquo;batteries included&amp;rdquo; system like &lt;a href=&#34;https://github.com/facebookincubator/create-react-app&#34;&gt;Create React App&lt;/a&gt; or &lt;a href=&#34;https://ember-cli.com/&#34;&gt;Ember CLI&lt;/a&gt;.  Making these distinctions is important for helping developers who may feel overwhelmed by all the concepts they need to learn when getting started with web development.&lt;/p&gt;
&lt;h4 id=&#34;big-team-vs-small-team-vs-individual&#34;&gt;Big Team vs Small team vs Individual&lt;/h4&gt;
&lt;p&gt;Another dynamic that matters when expressing best practices is the size of a team working on a project.  If a project is being developed by a large team, or several teams, or is meant to be used as a library by many people, techniques like automated documentation, static type checking, and clear style guidelines may be essential.  But for a personal project or a professional project run by a 1 person team, those same techniques may provide a lot of overhead for minimal benefit. Most teams will fall between those extremes and will have to weigh the tradeoffs in each case.&lt;/p&gt;
&lt;h4 id=&#34;personal-project-vs-internal-tool-vs-b2b-products-vs-consumer-products&#34;&gt;Personal Project vs Internal tool vs B2B Products vs Consumer Products&lt;/h4&gt;
&lt;p&gt;The audience of a project is also important.  Some projects we build for ourselves.  Some may be internal for a company, or for a group that we&amp;rsquo;re a part of.  Other projects are sold professionally to businesses or offered freely to consumers on the web.  There are different goals and expectations for each of these groups, that may impact which practices and techniques are important.  For instance, nobody cares if a personal web application you&amp;rsquo;ve made to organize your todos crashes in Internet Explorer or doesn&amp;rsquo;t have alt-text for images.  But browser compatibility and accessibility might be extremely important for a consumer web app aimed at a broad population.  Similarly, it might be ok for your internal web tool to have un-minified JavaScript and large un-optimized CSS and JavaScript bundles, since it will always be served locally over a fast connection.  But it could severely hurt the user experience to do the same things for a high traffic public site.&lt;/p&gt;
&lt;h4 id=&#34;web-page-vs-web-app&#34;&gt;Web page vs Web app&lt;/h4&gt;
&lt;p&gt;Distinguishing between web pages&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; and web apps&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; would short circuit a large number of internet arguments before they started.  Specifically arguments about progressive enhancement, whether we use too much JavaScript and whether a site is &amp;ldquo;acceptable&amp;rdquo; if it doesn&amp;rsquo;t work without JavaScript.  Many accessibility and performance proponents push very strongly for less JavaScript and sites that work without JavaScript.  And that is a good thing&amp;hellip; for the sites that &lt;strong&gt;can&lt;/strong&gt; function without JavaScript.  Web apps like Trello, Google Docs, or Postman just don&amp;rsquo;t make sense without JavaScript.  But saying that we should use less JavaScript isn&amp;rsquo;t bad advice, it&amp;rsquo;s just bad advice when given or taken without context.&lt;/p&gt;
&lt;h4 id=&#34;existing-project-vs-greenfield-project&#34;&gt;Existing project vs Greenfield project&lt;/h4&gt;
&lt;p&gt;Some choices are only easy to make at the start of a project.  It is possible to change the language or framework a project is written in midstream, but it is often extremely risky and painful.  So asking a developer working on a 5 year old JavaScript project with thousands of lines of code why they didn&amp;rsquo;t write it in &lt;a href=&#34;http://elm-lang.org/&#34;&gt;Elm&lt;/a&gt; or &lt;a href=&#34;https://clojurescript.org/&#34;&gt;ClojureScript&lt;/a&gt; is not helpful.  But suggesting that somebody write a new project in Elm may be just fine.&lt;/p&gt;
&lt;h4 id=&#34;short-term-project-vs-long-term-project&#34;&gt;Short term project vs Long term project&lt;/h4&gt;
&lt;p&gt;Some software projects are meant to be written, completed, and never seen again.  For instance a promotional site for an event.  Some projects, like financial software, are meant to last for decades.  This is yet another distinction than can impact best practice discussions.  When working on a short term project, speed of delivery and initial quality tend to matter a lot.  For long term projects it may be better to prioritize maintainability, security and ease of deployment.&lt;/p&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;Web page: sites that are mostly content focused with some possible interactivity layered on top&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;Web app: sites that are primarily an interactive experience for the user and behave more like traditional desktop or mobile applications&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>Evaluating Web Apps With Lighthouse</title>
      <link>https://benmccormick.org/2017/02/13/223000.html</link>
      <pubDate>Mon, 13 Feb 2017 23:30:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2017/02/14/223000.html</guid>
      <description>&lt;p&gt;Last year Google coined the term &amp;ldquo;Progressive Web App&amp;rdquo; as a way of describing the type of sites and applications that they think are the future of the web.  Progressive Web Apps are sites that load quickly, are always responsive to user input, work as well as possible offline, and integrate with native platforms like native apps.  While this site is not an &amp;ldquo;app&amp;rdquo; per say, I do want it to be as fast and responsive as possible, and I also wanted to better understand what Google is pulling under the PWA umbrella.  Fortunately, Google has built a tool &lt;a href=&#34;https://developers.google.com/web/tools/lighthouse/&#34;&gt;Lighthouse&lt;/a&gt; to help developers profile and improve their web applications, comparing them to a set of PWA benchmarks.  So I took this site through Lighthouse, and worked against their suggestions with the goal of learning more about PWAs and improving the experience of using benmccormick.org.  I&amp;rsquo;m passing along my experience here.&lt;/p&gt;
&lt;h3 id=&#34;getting-started&#34;&gt;Getting Started&lt;/h3&gt;
&lt;p&gt;I began by downloading the Lighthouse extension in the &lt;a href=&#34;https://chrome.google.com/webstore/detail/lighthouse/blipmdconlkpinefehnmjammfjpmpbjk&#34;&gt;Chrome Web Store&lt;/a&gt;.  Lighthouse can be installed either as a chrome extension or a node command line tool.  Both produce the same HTML report, but I chose the chrome extension for the convenience of keeping everything in the browser.  When I ran the initial report, I got the following result:&lt;/p&gt;
&lt;img alt=&#34;first score: 48/100&#34; src=&#34;first_report_summary.png&#34; class=&#34;full-width bordered-img&#34;&gt;
&lt;p&gt;48 out of 100 didn&amp;rsquo;t seem like a bad starting place.  Scrolling down it looked like I was mainly dinged on a few main areas:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;I had no offline support&lt;/li&gt;
&lt;li&gt;I did&amp;rsquo;t have any special setup for being included on a users homescreen. (I did have platform appropriate icons, but no app configuration)&lt;/li&gt;
&lt;li&gt;I had some possible inefficiencies in the assets I loaded.&lt;/li&gt;
&lt;/ol&gt;
&lt;img alt=&#34;offline issues&#34; src=&#34;first_report_offline.png&#34; class=&#34;full-width bordered-img&#34;&gt;
&lt;img alt=&#34;native issues&#34; src=&#34;first_report_native.png&#34; class=&#34;full-width bordered-img&#34;&gt;
&lt;img alt=&#34;asset issues&#34; src=&#34;first_report_assets.png&#34; class=&#34;full-width bordered-img&#34;&gt;
&lt;p&gt;Native app support isn&amp;rsquo;t a huge priority for me, and the assets issue seemed small, so I decided to investigate the offline support issue first.&lt;/p&gt;
&lt;h3 id=&#34;offline&#34;&gt;Offline&lt;/h3&gt;
&lt;p&gt;I based my service worker implementation off of &lt;a href=&#34;https://github.com/chriscoyier/Simple-Offline-Site&#34;&gt;Simple Offline Site&lt;/a&gt; a demo Service Worker repo created by Chris Coyier for an article on &lt;a href=&#34;https://css-tricks.com/serviceworker-for-offline/&#34;&gt;CSS Tricks&lt;/a&gt;.  This was perfect since it&amp;rsquo;s default behavior was what I wanted: cache everything, and check for updates from the server everytime we return from cache so we&amp;rsquo;re never out of date for long.  You can see what I did specifically in my &lt;a href=&#34;https://github.com/benmccormick/benmccormickorg/blob/master/pages/sw.es6&#34;&gt;github repo for this site&lt;/a&gt;. After adding the service worker, my score moved up to 63/100.&lt;/p&gt;
&lt;p&gt;Finally, Service Workers only work on HTTPS connections, but most links to my site are not https currently. So to take full advantage (and to address another metric I was flagged on), I used a &lt;a href=&#34;https://support.cloudflare.com/hc/en-us/articles/200170536-How-do-I-redirect-all-visitors-to-HTTPS-SSL-&#34;&gt;CloudFlare page rule&lt;/a&gt; to redirect all visting traffic to use https.  That bumped me up to 69/100.&lt;/p&gt;
&lt;img alt=&#34;asset issues&#34; src=&#34;second_report_offline.png&#34; class=&#34;full-width bordered-img&#34;&gt;
&lt;h3 id=&#34;native-support&#34;&gt;Native Support&lt;/h3&gt;
&lt;p&gt;As I said previously, native platform support isn&amp;rsquo;t a major priority for this blog, but I was curious about the process.  Getting native support turned out to be very straightforward.  I had already collected icons for the various platforms, and created a simple manifest when I originally created a favicon for my site.  But the manifest file didn&amp;rsquo;t have everything and it wasn&amp;rsquo;t being deployed properly to my site.  Fixing that and making it available at &lt;code&gt;/manifest.json&lt;/code&gt;, fixed all of the problems related to native platform support.&lt;/p&gt;
&lt;p&gt;My manifest file now looks like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;{
	&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;benmccormick.org&amp;#34;&lt;/span&gt;,
  &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;short_name&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;benmccormick&amp;#34;&lt;/span&gt;,
	&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;icons&amp;#34;&lt;/span&gt;: [
		{
			&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;src&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;\/android-chrome-192x192.png?v=yyxgnp97qG&amp;#34;&lt;/span&gt;,
			&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;sizes&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;192x192&amp;#34;&lt;/span&gt;,
			&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;image\/png&amp;#34;&lt;/span&gt;
		},
		{
			&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;src&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;\/android-chrome-384x384.png?v=yyxgnp97qG&amp;#34;&lt;/span&gt;,
			&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;sizes&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;384x384&amp;#34;&lt;/span&gt;,
			&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;image\/png&amp;#34;&lt;/span&gt;
		}
	],
	&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;theme_color&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;#ffffff&amp;#34;&lt;/span&gt;,
	&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;background_color&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;#57A3E8&amp;#34;&lt;/span&gt;,
	&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;display&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;browser&amp;#34;&lt;/span&gt;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;After correctly deploying that manifest file, my score moved all the way up to 100/100!&lt;/p&gt;
&lt;img alt=&#34;asset issues&#34; src=&#34;third_report_native.png&#34; class=&#34;full-width bordered-img&#34;&gt;
&lt;p&gt;I clearly benefited from starting in a good spot.  &lt;a href=&#34;https://github.com/gatsbyjs/gatsby&#34;&gt;Gatsby&lt;/a&gt; is &amp;ldquo;fast by default&amp;rdquo; as a platform for building blogs, and I&amp;rsquo;ve done my best to avoid making it slow.  But it was fun seeing what I could do to make the site a better experience for users with bad connectivity, and to learn more about what Google is trying to do with PWAs.&lt;/p&gt;
&lt;h3 id=&#34;more-resources&#34;&gt;More Resources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Google has a bunch of resources around creating Progressive Web Apps.  You can find them on &lt;a href=&#34;https://developers.google.com/web/progressive-web-apps/&#34;&gt;their PWA landing page&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;It was so easy to make my blog a PWA mostly because it is built on &lt;a href=&#34;https://github.com/gatsbyjs/gatsby&#34;&gt;Gatsby&lt;/a&gt;. Worth looking at if you&amp;rsquo;re a web developer who blogs.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>MobX: First Impressions</title>
      <link>https://benmccormick.org/2017/01/09/083000.html</link>
      <pubDate>Mon, 09 Jan 2017 09:30:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2017/01/09/083000.html</guid>
      <description>&lt;p&gt;I spent some time around the holidays this year playing with &lt;a href=&#34;https://mobx.js.org/&#34;&gt;MobX&lt;/a&gt;, a state management library for JavaScript.  MobX is an unopinionated library that provides a layer over normal JavaScript data structures that allow other code to efficiently observe data changes and update based on what has changed.  It&amp;rsquo;s an interesting tool for handling state in web applications, especially in existing projects that might need to update state handling iteratively.  Here are some first impressions.&lt;/p&gt;
&lt;h3 id=&#34;what-is-mobx&#34;&gt;What is MobX?&lt;/h3&gt;
&lt;p&gt;MobX has 3 core concepts developers need to understand:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Observable state&lt;/strong&gt; - MobX provides functions to make data &lt;em&gt;observable&lt;/em&gt;.  Observable data can be watched by other pieces of code which may efficiently update when the state changes.  Observable data is primarily created in MobX using the &lt;code&gt;observable&lt;/code&gt; function.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Derivations&lt;/strong&gt; - Functions that &lt;em&gt;watch&lt;/em&gt; observable data are called derivations.  MobX has 2 primary types of derivations: &lt;em&gt;computed values&lt;/em&gt; and &lt;em&gt;reactions&lt;/em&gt;.  Computed values update a value based on other data, while reactions produce side effects: updates to a UI, a network call, or a logging statement for example. MobX provides a &lt;code&gt;computed&lt;/code&gt; function for defining computed values; in most cases reactions will likely be mostly defined using a framework specific helper library like &lt;a href=&#34;https://github.com/mobxjs/mobx-react&#34;&gt;mobx-react&lt;/a&gt; or &lt;a href=&#34;https://github.com/500tech/ng2-mobx&#34;&gt;ng2-mobx&lt;/a&gt;.  MobX does provide some lower level libraries for reactions though, including &lt;code&gt;autorun&lt;/code&gt; and &lt;code&gt;when&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Actions&lt;/strong&gt; - Code that updates observable state is known as an action.  MobX has a formalized version of actions which can be defined using the &lt;code&gt;action&lt;/code&gt; function, but it is also possible to modify state directly using any normal JavaScript code and maintain observable behavior.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In practice this looks something like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; React from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;react&amp;#39;&lt;/span&gt;;
&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; ReactDOM from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;react-dom&amp;#39;&lt;/span&gt;;
&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; {observable} from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;mobx&amp;#39;&lt;/span&gt;;
&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; {observer} from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;mobx-react&amp;#39;&lt;/span&gt;;

&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; digits &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; observable([&lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;, &lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt;]);

&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; DigitPrinter &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; observer(({digits}) =&amp;gt; {
  &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; (&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;div&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;
    {digits.join(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;, &amp;#39;&lt;/span&gt;)}
  &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;/div&amp;gt;);
});

ReactDOM.render( &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;DigitPrinter digits &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {digits} &lt;span style=&#34;color:#ff79c6&#34;&gt;/&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;document&lt;/span&gt;.getElementById(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;root&amp;#39;&lt;/span&gt;));

&lt;span style=&#34;color:#6272a4&#34;&gt;/* prints 1, 2 */&lt;/span&gt;


digits.push(&lt;span style=&#34;color:#bd93f9&#34;&gt;3&lt;/span&gt;);

&lt;span style=&#34;color:#6272a4&#34;&gt;/* DOM re-renders to print 1, 2, 3 */&lt;/span&gt;

digits[&lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt;] &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;4&lt;/span&gt;;

&lt;span style=&#34;color:#6272a4&#34;&gt;/* DOM re-renders to print 1, 2, 4 */&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The component is able to passively &lt;em&gt;observe&lt;/em&gt; changes in the data, and re-render when it changes.  But MobX is actually even smarter than this example shows.  Let&amp;rsquo;s look at another example, this time using a more complex data structure (a class).&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; React from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;react&amp;#39;&lt;/span&gt;;
&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; ReactDOM from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;react-dom&amp;#39;&lt;/span&gt;;
&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; {extendObservable} from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;mobx&amp;#39;&lt;/span&gt;;
&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; {observer} from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;mobx-react&amp;#39;&lt;/span&gt;;
&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; moment from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;moment&amp;#39;&lt;/span&gt;;

&lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; Appointment {

  constructor() {
    extendObservable(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;, {
      dueDate&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;01-01-2017&amp;#39;&lt;/span&gt;,
      title&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Dinner with Joe&amp;#39;&lt;/span&gt;
      location&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Chik-Fil-A&amp;#39;&lt;/span&gt;,
      isToday&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; computed(&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;() {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; moment(dueDate, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;MM-DD-YYYY&amp;#39;&lt;/span&gt;).diff(moment.now(), &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;days&amp;#39;&lt;/span&gt;) &lt;span style=&#34;color:#ff79c6&#34;&gt;===&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;0&lt;/span&gt;;
      }),
    });
  }

  toString() {
    &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;`&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.title&lt;span style=&#34;color:#f1fa8c&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt; @ &lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.location&lt;span style=&#34;color:#f1fa8c&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;`&lt;/span&gt;;
  }
}


&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; TodayBox &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; observer(&lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; TodayBox &lt;span style=&#34;color:#ff79c6&#34;&gt;extends&lt;/span&gt; React.Component {
  render () {
    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; {appointments} &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.props;
    &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; (&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;div&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;
      {appointments.filter(a =&amp;gt; a.isToday).map(a =&amp;gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;span&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;a.toString()&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;/span&amp;gt;)}     
    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;/div&amp;gt;);
  }
});

&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; appointment &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; Appointment();

ReactDOM.render( &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;TodayBox appointments &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {[appointment]} &lt;span style=&#34;color:#ff79c6&#34;&gt;/&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;document&lt;/span&gt;.getElementById(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;root&amp;#39;&lt;/span&gt;));

&lt;span style=&#34;color:#6272a4&#34;&gt;/* prints an empty div */&lt;/span&gt;

appointment.title &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Dinner with Bob&amp;#39;&lt;/span&gt;;

&lt;span style=&#34;color:#6272a4&#34;&gt;/* Nothing relevant has changed. The component does not re-render */&lt;/span&gt;

appointment.dueDate &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;01-09-2017&amp;#39;&lt;/span&gt;;  

&lt;span style=&#34;color:#6272a4&#34;&gt;/*  assume that 01-09-2017 is &amp;#34;today&amp;#34; */&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;MobX has the &amp;ldquo;magical&amp;rdquo; ability to determine what changes actually affect the observer and not make unnecessary calls of reaction functions.  In practice, that magic allows you to write less, more efficient code for updating your UI based on data.&lt;/p&gt;
&lt;h3 id=&#34;how-does-mobx-work&#34;&gt;How Does MobX work?&lt;/h3&gt;
&lt;p&gt;I have a learned skepticism of magical solutions like this.  Generally I find that time-saving magic like this ends up costing time when it comes to maintenance, and explicit relationships between code saves time over less-boilerplate heavy code. Fortunately, while the libraries code itself is fairly complex, it isn&amp;rsquo;t too hard to understand the logic behind how MobX works.&lt;/p&gt;
&lt;p&gt;On the Observer side, MobX uses &lt;a href=&#34;http://benmccormick.org/2015/09/14/es5-es6-es2016-es-next-whats-going-on-with-javascript-versioning/&#34;&gt;ES5&lt;/a&gt; setters and getters to proxy updates to observable data structure and listen in when data is updated.  This allows the type of event listening that &lt;a href=&#34;http://backbonejs.org/&#34;&gt;Backbone&lt;/a&gt; and other libraries provide, without requiring the user to go through special &lt;code&gt;set&lt;/code&gt; or &lt;code&gt;get&lt;/code&gt; methods to update an object&amp;rsquo;s properties.  Most of the time you should be able to just be able to write code as you normally would, and MobX will make it work.  There are some exceptions though that mean its important to actually understand how the library work.  Getters and Setters only work when looking up an existing property on an object, so when using primitive values or adding new values to an existing object, some special syntax (the return of &lt;code&gt;get&lt;/code&gt; and &lt;code&gt;set&lt;/code&gt; methods) may be required.  In Mobx primitive observables are referred to as &lt;em&gt;boxed&lt;/em&gt; values, and objects that require new values over time can be handled by using observable Maps, which use the API of &lt;a href=&#34;http://benmccormick.org/2015/09/14/es5-es6-es2016-es-next-whats-going-on-with-javascript-versioning/&#34;&gt;ES6&lt;/a&gt; Maps.&lt;/p&gt;
&lt;p&gt;On the derivative side, reactions and computed values are always defined as functions.  MobX wraps these functions and is able to determine (through the method described above) what properties were accessed during each function run.  It then only listens for changes to these properties.  Thus it doesn&amp;rsquo;t matter if you theoretically could access thousands of observable properties in a function, if you wrap those references in an if statement to a single property, and that property returns false on first run, the derivative function will only listen for changes on that property before running again. When an observable is updated, all derivative code is run synchronously and atomically so there is no concern of getting into bad intermediate states.&lt;/p&gt;
&lt;p&gt;Most of the &amp;ldquo;magic&amp;rdquo; is covered by the 2 paragraphs above, and once you understand the ideas behind them (see the resources at the bottom of this post for more in-depth explanations), it is fairly easy to understand the reasoning behind the cases where the magic fails.&lt;/p&gt;
&lt;h3 id=&#34;decorators&#34;&gt;Decorators&lt;/h3&gt;
&lt;p&gt;Developers who actually use MobX are probably questioning my examples by now, because I&amp;rsquo;ve been using a different syntax than the primary MobX documentation for showing my examples.  So let&amp;rsquo;s talk about decorators.  The preferred way (according to the documentation) to write MobX code is to use decorators to define observers and observables.  Decorators are a &lt;a href=&#34;http://tc39.github.io/proposal-decorators/&#34;&gt;proposed new JavaScript feature&lt;/a&gt; for declaratively adding extra behavior to classes, class properties and class methods.  Using them with MobX, my above example would look like this &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;
&lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; Appointment {

  @observable dueDate &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;01-01-2017&amp;#39;&lt;/span&gt;
  @observable title &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Dinner with Joe&amp;#39;&lt;/span&gt;
  @observable location &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Chik-Fil-A&amp;#39;&lt;/span&gt;

  @computed get isToday() {
    &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; moment(dueDate, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;MM-DD-YYYY&amp;#39;&lt;/span&gt;).diff(moment.now(), &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;days&amp;#39;&lt;/span&gt;) &lt;span style=&#34;color:#ff79c6&#34;&gt;===&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;0&lt;/span&gt;;
  }

  toString() {
    &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;`&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.title&lt;span style=&#34;color:#f1fa8c&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt; @ &lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.location&lt;span style=&#34;color:#f1fa8c&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;`&lt;/span&gt;;
  }
}


@observer &lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; TodayBox &lt;span style=&#34;color:#ff79c6&#34;&gt;extends&lt;/span&gt; React.Component {
  render () {
    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; {appointments} &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.props;
    &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; (&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;div&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;
      {appointments.filter(a =&amp;gt; a.isToday).map(a =&amp;gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;span&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;a.toString()&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;/span&amp;gt;)}     
    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;/div&amp;gt;);
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That obviously looks a lot cleaner than my example.  So what&amp;rsquo;s the problem?  Again, decorators are a &lt;em&gt;proposed&lt;/em&gt; JavaScript feature.  Currently they&amp;rsquo;re in Stage 2, which means roughly that they are very likely to eventually make it into the language, but may change in non-trivial ways before that happens.  Currently decorators are implemented in &lt;a href=&#34;https://www.typescriptlang.org/docs/handbook/decorators.html&#34;&gt;TypeScript&lt;/a&gt;, as well as a &lt;a href=&#34;https://github.com/loganfsmyth/babel-plugin-transform-decorators-legacy&#34;&gt;3rd party babel plugin&lt;/a&gt;, but as of January 2017 &lt;a href=&#34;http://kangax.github.io/compat-table/esnext/#test-class_decorators&#34;&gt;are not implemented in any browser engines&lt;/a&gt;, and are not implemented in any first party babel plugins &lt;a href=&#34;https://github.com/babel/babel/issues/2645&#34;&gt;due to spec instability&lt;/a&gt;.  Decorators are a key part of Angular2, and are used by other frameworks including &lt;a href=&#34;http://aurelia.io/&#34;&gt;Aurelia&lt;/a&gt; and &lt;a href=&#34;https://github.com/rwjblue/ember-computed-decorators&#34;&gt;Ember&lt;/a&gt;, so I don&amp;rsquo;t think they&amp;rsquo;re going away.  But I also don&amp;rsquo;t see them as ready for production use for teams that don&amp;rsquo;t have the capacity to dedicate the time to update existing code if/when the spec changes&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;.  If for one reason or other you&amp;rsquo;re comfortable with the risks however, decorators are a great way to clean up the MobX API, and I&amp;rsquo;m excited for the spec to get to the point where I can use them.&lt;/p&gt;
&lt;h3 id=&#34;comparison-to-redux-and-setstate&#34;&gt;Comparison to Redux and setState&lt;/h3&gt;
&lt;p&gt;As a state management library that was built to be used with React, the obvious questions to ask about MobX are how it improves over React&amp;rsquo;s built in state handling, and how it compares to &lt;a href=&#34;http://redux.js.org/&#34;&gt;Redux&lt;/a&gt;, the current most popular state management solution for React. MobX takes a different approach to each.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s important to say at the start that MobX isn&amp;rsquo;t mutually exclusive with using setState.  It&amp;rsquo;s possible to use them together, with MobX managing application data and setState handling individual component/UI state.  But there is some advantages to using MobX for UI state as well.  The biggest reason is that MobX is smarter than setState about when re-rendering is required.  By default React Components re-render on any call to setState, regardless of whether the state change actually affects what is rendered or not. MobX&amp;rsquo;s creator &lt;a href=&#34;https://medium.com/@mweststrate/3-reasons-why-i-stopped-using-react-setstate-ab73fc67a42e#.x0o6y4rxv&#34;&gt;wrote more about this on Medium&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Comparing MobX and Redux could be a whole article on its own, so I&amp;rsquo;m not going to go too deep here, but suffice it to say that MobX is more flexible than Redux, but as a result loses some of the benefits of Redux&amp;rsquo;s structured approach.  Specifically, it is easy to convert a single object to become a MobX observable and use it in an existing React component.  It can be easily inlined in an existing file and used for one component even.  You also don&amp;rsquo;t have to deal with the ceremony of using &lt;a href=&#34;http://benmccormick.org/2016/06/04/what-are-mutable-and-immutable-data-structures-2/&#34;&gt;immutable data&lt;/a&gt;.  Redux is intended as a solution that will take over all your state, and doesn&amp;rsquo;t scale down nearly as well or mix with other solutions &lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;.  However, Redux&amp;rsquo;s structure also has benefits.  It allows easy testings of each component of an app individually, the creation of powerful tooling that will work with any Redux app, and reliable guarantees of how state will be updated.  These things are mostly possible with MobX &lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;, but require more developer discipline, and/or can&amp;rsquo;t be written as easily as universal tools. Overgeneralizing, I would prefer Redux in a new application, but would look to MobX for improving data management in an existing application.  MobX also has advantages in applications where you&amp;rsquo;re displaying a large amount of UI elements based on a relatively small amount of data, or have a lot of derived data (something like a spreadsheet), whereas Redux has benefits for applications that need to be extremely reliable and well tested.&lt;/p&gt;
&lt;h3 id=&#34;stray-thoughts&#34;&gt;Stray Thoughts&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;If you do want more discipline in MobX, make sure to use &lt;code&gt;useStrict&lt;/code&gt; to require updates to use Actions&lt;/li&gt;
&lt;li&gt;MobX has a nice set of &lt;a href=&#34;https://github.com/mobxjs/mobx-react-devtools&#34;&gt;devtools&lt;/a&gt; that are useful if you&amp;rsquo;re opting in to using actions, and using React with MobX.&lt;/li&gt;
&lt;li&gt;If this isn&amp;rsquo;t clear yet, I definitely recommend hacking around with Mobx&amp;rsquo;s low level APIs to learn more about how it works before integrating it straight into a framework&lt;/li&gt;
&lt;li&gt;&lt;del&gt;Also note that MobX 3.0 is imminent, there is a release candidate that you can play with now.&lt;/del&gt; &lt;strong&gt;Update:&lt;/strong&gt; That didn&amp;rsquo;t take long.  &lt;a href=&#34;https://medium.com/@mweststrate/mobx-3-released-unpeeling-the-onion-ca877382f443#.mk6mdypt2&#34;&gt;MobX 3.0 is out&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;more-resources&#34;&gt;More Resources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The two most helpful resources I found for conceptually understanding MobX were in-depth articles by the library&amp;rsquo;s author &lt;a href=&#34;&#34;&gt;Michael Westrate&lt;/a&gt;: &lt;a href=&#34;https://medium.com/@mweststrate/becoming-fully-reactive-an-in-depth-explanation-of-mobservable-55995262a254#.jd4hgh2zi&#34;&gt;Becoming fully reactive: an in-depth explanation of MobX&lt;/a&gt; on Medium and &lt;a href=&#34;https://mobx.js.org/intro/concepts.html&#34;&gt;Concepts &amp;amp; Principles&lt;/a&gt; from the MobX documentation&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;This &lt;a href=&#34;https://twitter.com/AdamRackis/status/775706291259908096&#34;&gt;tweet thread&lt;/a&gt; and the linked article, are a good breakdown of the tradeoffs between MobX and Redux&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;Technically this also uses class properties as well, another proposal that works well with decorators&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;It&amp;rsquo;s possible any spec changes will be trivially fixable with a code mod script, but right now there is more uncertainty than I am personally comfortable with.  I&amp;rsquo;m grateful to people who are willing to take more risks here than me, they push the language forward.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;I&amp;rsquo;m talking here about what is encouraged and easy, not what is possible.  It is of course possible to mix in Redux with other solutions.&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;MobX has some nice &lt;a href=&#34;https://github.com/mobxjs/mobx-react-devtools&#34;&gt;devtools!&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>Orthogonality and CSS in JS</title>
      <link>https://benmccormick.org/2017/01/02/190000.html</link>
      <pubDate>Mon, 02 Jan 2017 20:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2017/01/03/190000.html</guid>
      <description>&lt;p&gt;One of the realities of the constant change in the web development world is that &amp;ldquo;best practices&amp;rdquo; are often hotly contested.  One issue that the front end community doesn&amp;rsquo;t seem to have come to a consensus on yet is how tightly to bundle JavaScript, HTML and CSS in code.  Should they be bundled and managed completely separately?  Kept in different files and imported together into JavaScript component files?  Or can we remove HTML and CSS files entirely and generate everything in JavaScript? This is a discussion that still comes up all the time in my &lt;a href=&#34;https://twitter.com/thomasfuchs/status/810885087214637057&#34;&gt;twitter&lt;/a&gt; &lt;a href=&#34;https://twitter.com/TheLarkInn/status/812089065210335232&#34;&gt;feed&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Many new frameworks that encourage a component based architecture (including React, Vue, and Angular2 &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;) provide affordances for including HTML and CSS directly in JavaScript, but those solutions are not yet used universally.  Many people are still very happy keeping CSS bundled separately.  I have no idea what the &lt;em&gt;best&lt;/em&gt; solution is.  But I am interested in how people talk about the problem.  One major argument I have seen from people advocating both sides is that their preferred approach encourages good &amp;ldquo;separation of concerns&amp;rdquo;.&lt;/p&gt;
&lt;blockquote class=&#34;twitter-tweet&#34; data-lang=&#34;en&#34;&gt;&lt;p lang=&#34;en&#34; dir=&#34;ltr&#34;&gt;I&amp;#39;m moving from storing my CSS, JS and HTML in different files, to physically putting them on different drives. Keep those concerns separate&lt;/p&gt;&amp;mdash; Ben Lesh (@BenLesh) &lt;a href=&#34;https://twitter.com/BenLesh/status/812092408519413761&#34;&gt;December 23, 2016&lt;/a&gt;&lt;/blockquote&gt;
&lt;p&gt;I&amp;rsquo;d like to take a deeper look at this and give some vocabulary that can hopefully help anyone working through discussions on how to manage CSS for components.  I&amp;rsquo;ll focus specifically on CSS since frameworks tend to be more agnostic to how it is blended with JS than they are about HTML, and on components since that is the main context in which people are arguing for blending of css. For this piece, I&amp;rsquo;ll consider a component to be a set of HTML, CSS, and JavaScript that combine to form a reusable piece of UI &lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;h3 id=&#34;orthogonality-cohesion-and-coupling&#34;&gt;Orthogonality, Cohesion, and Coupling&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;http://amzn.to/2hNzQ0t&#34;&gt;The Pragmatic Programmer&lt;/a&gt;, one of the best books ever written on Software Engineering, uses the following three terms when talking about &amp;ldquo;Separation of Concerns&amp;rdquo;: orthogonality, cohesion, and coupling.&lt;/p&gt;
&lt;p&gt;Orthogonality is the idea that modules should be written in a way that a change in one module should not require changes in any other module.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Two or more things are orthogonal if changes in one do not affect any of the others. In a well-designed system, the database code will be orthogonal to the user interface: you can change the interface without affecting the database, and swap databases without changing the interface.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;— The Pragmatic Programmer&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Cohesion is a measure of how well the internal contents of a module relate to each other. A cohesive module is one with a single well defined purpose, where all code in the module is related to that purpose.  A less cohesive module might have multiple purposes, with pieces of code that are completely unrelated to each other.  &lt;a href=&#34;https://sites.google.com/site/unclebobconsultingllc/&#34;&gt;Robert C. Martin&lt;/a&gt; describes this as each module having &amp;ldquo;a single reason to change&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Coupling is a measure of how dependent different modules are on the internal workings of other modules. In a loosely coupled system, any module can be completely rewritten as long as it exposes the same public interface, without any other modules needing to change.  In a tightly coupled system, changing the internal details of one module may require changes in many other modules.&lt;/p&gt;
&lt;p&gt;In the real world most systems are not purely orthogonal, and their modules are likely not 100% cohesive and uncoupled.  But striving for these goals is a good approximation of what many people mean when they talk about &lt;em&gt;separation of concerns&lt;/em&gt;.&lt;/p&gt;
&lt;h3 id=&#34;conways-law&#34;&gt;Conways Law&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;http://amzn.to/2hNzQ0t&#34;&gt;The Pragmatic Programmer&lt;/a&gt; does touch on another application of orthogonality to software engineering:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Have you noticed how some project teams are efficient, with everyone knowing what to do and contributing fully, while the members of other teams are constantly bickering and don&amp;rsquo;t seem able to get out of each other&amp;rsquo;s way?&lt;/p&gt;
&lt;p&gt;Often this is an orthogonality issue. When teams are organized with lots of overlap, members are confused about responsibilities. Every change needs a meeting of the entire team, because any one of them might be affected.&lt;/p&gt;
&lt;p&gt;How do you organize teams into groups with well-defined responsibilities and minimal overlap? There&amp;rsquo;s no simple answer. It depends partly on the project and your analysis of the areas of potential change. It also depends on the people you have available. Our preference is to start by separating infrastructure from application. Each major infrastructure component (database, communications interface, middleware layer, and so on) gets its own subteam. Each obvious division of application functionality is similarly divided. Then we look at the people we have (or plan to have) and adjust the groupings accordingly.&lt;/p&gt;
&lt;p&gt;You can get an informal measure of the orthogonality of a project team&amp;rsquo;s structure. Simply see how many people need to be involved in discussing each change that is requested. The larger the number, the less orthogonal the group. Clearly, an orthogonal team is more efficient.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;— The Pragmatic Programmer&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The idea is that teams work more efficiently when each can work in its own areas without having to be bogged down by using another group (or individuals) code, and only interacting with those modules through a well communicated interface.  This is also known as &lt;a href=&#34;https://en.wikipedia.org/wiki/Conway&#39;s_law&#34;&gt;Conway&amp;rsquo;s Law&lt;/a&gt;, which is often used disparagingly but still stands as a true observation about real life code.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;organizations which design systems &amp;hellip; are constrained to produce designs which are copies of the communication structures of these organizations&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;— Conway&amp;rsquo;s Law&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Although it usually isn&amp;rsquo;t phrased quite so explicitly, I believe Conway&amp;rsquo;s law is often related to what people mean when they discuss separation of concerns in front end development.&lt;/p&gt;
&lt;h3 id=&#34;boundaries-and-interfaces-between-css-and-javascript&#34;&gt;Boundaries and Interfaces between CSS and JavaScript&lt;/h3&gt;
&lt;p&gt;Let&amp;rsquo;s look at 2 examples of how CSS can be structured.  We&amp;rsquo;ll use a &amp;ldquo;page view counter&amp;rdquo; as our example. The element will show the number of users who have viewed the page, and respond to click events by showing a modal with the most popular pages on the site.
First, for a more traditional example, I&amp;rsquo;ll show a &lt;a href=&#34;http://marionettejs.com/&#34;&gt;Marionette&lt;/a&gt; View, with separate CSS. For a more integrated example, I&amp;rsquo;ll use a React component.&lt;/p&gt;
&lt;h4 id=&#34;marionette&#34;&gt;Marionette&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;//view-counter.js
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;
&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; Mn from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;backbone.marionette&amp;#39;&lt;/span&gt;;
&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; template from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;./view-counter.hbs&amp;#39;&lt;/span&gt;
&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; { getPageViews, showModal } from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;../util/page-views&amp;#39;&lt;/span&gt;;

&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; ViewCounter &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; Mn.View.extend({

  template,

  className&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;page-view-counter&amp;#39;&lt;/span&gt;,

  ui&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;  {
    &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;showPageViewsModal&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;.show-modal-js&amp;#39;&lt;/span&gt;,
  },

  events&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; {
    &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;click @ui.showPageViewsModal&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;showPageViewsModal&amp;#39;&lt;/span&gt;,
  }

  templateContext() {
      &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; {
        pageViews&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; getPageViews(),
      };
  },

  showPageViewsModal() {
    showModal();
  }

});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-hbs&#34; data-lang=&#34;hbs&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;{{!view-counter.hbs}}&lt;/span&gt;

&amp;lt;span class=&amp;#34;page-view-counter__title&amp;#34;&amp;gt; Page Views: &amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;#34;page-view-counter__counter show-modal-js&amp;#34;&amp;gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;{{&lt;/span&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;pageViews&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;}}&lt;/span&gt; &amp;lt;/span&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-css&#34; data-lang=&#34;css&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;//&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;view-counter&lt;/span&gt;.&lt;span style=&#34;color:#50fa7b&#34;&gt;css&lt;/span&gt;

.&lt;span style=&#34;color:#50fa7b&#34;&gt;page-view-counter&lt;/span&gt; {
  &lt;span style=&#34;color:#ff79c6&#34;&gt;display&lt;/span&gt;: &lt;span style=&#34;color:#ff79c6&#34;&gt;flex&lt;/span&gt;;
}

.&lt;span style=&#34;color:#50fa7b&#34;&gt;page-view-counter__title&lt;/span&gt; {
  &lt;span style=&#34;color:#ff79c6&#34;&gt;font-weight&lt;/span&gt;: &lt;span style=&#34;color:#bd93f9&#34;&gt;700&lt;/span&gt;;
  &lt;span style=&#34;color:#ff79c6&#34;&gt;padding&lt;/span&gt;: &lt;span style=&#34;color:#bd93f9&#34;&gt;3&lt;/span&gt;&lt;span style=&#34;color:#8be9fd&#34;&gt;px&lt;/span&gt;;
}

.&lt;span style=&#34;color:#50fa7b&#34;&gt;page-view-counter__counter&lt;/span&gt; {
  &lt;span style=&#34;color:#ff79c6&#34;&gt;padding&lt;/span&gt;: &lt;span style=&#34;color:#bd93f9&#34;&gt;3&lt;/span&gt;&lt;span style=&#34;color:#8be9fd&#34;&gt;px&lt;/span&gt;;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;react&#34;&gt;React&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;//view-counter.jsx
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; React from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;react&amp;#39;&lt;/span&gt;;
&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; { showModal } from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;../util/page-views&amp;#39;&lt;/span&gt;;

&lt;span style=&#34;color:#ff79c6&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; PageViewCounter &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; (props) =&amp;gt; {
    &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;div style &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {{display&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;flex&amp;#39;&lt;/span&gt;}}&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;
      &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;span style &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {{
        fontWeight&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;700&lt;/span&gt;,
        padding&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;3px&amp;#39;&lt;/span&gt;,
      }}&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;
        Page Views&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;
      &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;/span&amp;gt;
      &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;span style &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {{padding&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;3px&amp;#39;&lt;/span&gt;}}&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;{&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.props.pageViews}&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;/span&amp;gt;
    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;/div&amp;gt;
}

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The React and Marionette examples have set different module boundaries. In the Marionette example, we have defined 3 modules, split by code type.  Ignoring the leaky abstractions in the Marionette boundaries &lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;, we can say we have 3 modules with clear singular purpose (styling, behavior,  structure) that use class names and  &lt;code&gt;templateContext&lt;/code&gt; as interfaces.  The handlebars file exposes classes, which the CSS uses to style elements and the JavaScript code uses as attachment points for event handling.  The JavaScript view passes data to the template through templateContext.  In the React code we have defined a single module that exports a component as its only external interface. The module&amp;rsquo;s single purpose could be defined as &amp;ldquo;rendering a PageViewCounter&amp;rdquo;.&lt;/p&gt;
&lt;h3 id=&#34;how-do-we-define-module-boundaries&#34;&gt;How do we define module boundaries?&lt;/h3&gt;
&lt;p&gt;If you&amp;rsquo;re excited to read which of the above examples is the &lt;em&gt;correct&lt;/em&gt; module boundary definition, I&amp;rsquo;m sorry to disappoint you.  It turns out that module boundaries are more of an art than a science.  Let&amp;rsquo;s consider each of these examples by the criteria we laid out above.&lt;/p&gt;
&lt;p&gt;The Marionette modules are &lt;strong&gt;cohesive&lt;/strong&gt;.  Each module is single purpose, with a clear reason why it might change.  The React module is also cohesive, as it describes a single atomic component. However, it has more reasons it might change.  We might change that module because of a change in the look and feel of the site, because of a change in the expected behavior of the click event, or because we&amp;rsquo;re changing the text inside the component.&lt;/p&gt;
&lt;p&gt;The Marionette modules are not quite &lt;strong&gt;decoupled&lt;/strong&gt;.  While this CSS doesn&amp;rsquo;t nest selectors and we don&amp;rsquo;t have any explicit dependencies on the HTML structure, it is still written in a way that assumes &lt;code&gt;.page-view-counter__title&lt;/code&gt; and &lt;code&gt;.page-view-counter__counter&lt;/code&gt; will be direct children of &lt;code&gt;.page-view-counter&lt;/code&gt;.  So changing the &amp;ldquo;internal details&amp;rdquo; of the Handlebars file by adding an extra element around those children would break the CSS. While the modules are not completely decoupled from each other, they don&amp;rsquo;t rely on any private details of other modules or global styles and can be used together as a reusable component.  The React module is similarly decoupled from the rest of the system, and as a single module faces no internal coupling issues.&lt;/p&gt;
&lt;p&gt;Both components should be &lt;strong&gt;orthogonal&lt;/strong&gt; from the rest of the system, even though the Marionette modules may be less orthogonal internally.  The question of how they meet a Conway&amp;rsquo;s law style of orthogonality depends on a team.  If your team has designers, and developers separately working on style/structure and behavior, the Marionette version may allow for more efficient division of labor, with communication centering on class based communication.  If you instead have a group of polyglot front end developers who implement mocks from designers across all 3 areas, the React version will instead present a simpler implementation that maps better to your team, with the focus on interfaces across different components.&lt;/p&gt;
&lt;p&gt;In the end decisions like this are an exercise in understanding context and preferences.  What will make your team productive? You can accept the coupling of the first example in order to gain the benefits of small focused modules.  Or you can take the larger scope of the React component in exchange for keeping all information relevant to a component in one place.  Are you making single developers responsible for a set of components?  Or are they responsible for behavior generally, with design handled by someone else? Make the decisions that work for your project.&lt;/p&gt;
&lt;h3 id=&#34;more-resources&#34;&gt;More Resources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://amzn.to/2hNzQ0t&#34;&gt;The Pragmatic Programmer&lt;/a&gt; is a great book. Much of the vocabulary in this post comes from its Chapter 8, but the whole book is worth a read and is highly recommended.&lt;/li&gt;
&lt;li&gt;CSS Tricks has a good look at the &lt;a href=&#34;https://css-tricks.com/the-debate-around-do-we-even-need-css-anymore/&#34;&gt;pros and cons of CSS in JS&lt;/a&gt;.  I focused on theory here, but this is much more hands on about the practical concerns around this debate.&lt;/li&gt;
&lt;/ul&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;This is a bit of a generalization.  React provides an abstraction over HTML that replaces hand-written HTML, but doesn&amp;rsquo;t specify anything for CSS, CSS in JS solutions are simply popular in that community.  Vue and Angular both allow  CSS and HTML to share a file with JS, but CSS can still be handled separately.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;There are some distinctions about CSS in JS vs importing CSS into JS using webpack that I&amp;rsquo;m not really dealing with here.  This is a post about how to think about these decisions moreso than the specific options for bundling CSS and JS&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;The root HTML element in any Marionette component is always defined implicitly in JavaScript, and Handlebars is an expressive templating language that can handle more than structure.&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>2016 Roundup</title>
      <link>https://benmccormick.org/2016/12/29/211500.html</link>
      <pubDate>Thu, 29 Dec 2016 22:15:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2016/12/30/211500.html</guid>
      <description>&lt;p&gt;Thanks to all of you who have followed my blog this year! It was a busy year and I didn&amp;rsquo;t get as many posts out as years past, but you all have been as supportive as ever.  I&amp;rsquo;m excited about the things I&amp;rsquo;ve been able to do with the new site this month, and am looking forward to a great 2017.  But first, a look back.&lt;/p&gt;
&lt;h3 id=&#34;most-read-posts-of-2016&#34;&gt;Most Read Posts of 2016&lt;/h3&gt;
&lt;p&gt;I wrote 15 posts in 2016, down from my pace of 19 in 2015 and 25 in 2014.  Some of that was an unusually busy work year, and some of the time I normally put into the site went to the redesdign. I also sat on a few articles that didn&amp;rsquo;t turn out that great when actually written out.  But I made a good run at the end and hopefully will be writing more in 2017.  The most read posts from this site in 2016 were:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;http://benmccormick.org/2016/01/11/the-most-interesting-atom-packages-ive-found-so-far/&#34;&gt;The Most Interesting Atom Packages I&amp;rsquo;ve found so far&lt;/a&gt; - I started using &lt;a href=&#34;https://atom.io/&#34;&gt;Atom&lt;/a&gt; as my primary text editor late in 2015.  This was my roundup of the coolest and most unique plugins I had found for Atom at that point.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;http://benmccormick.org/2016/09/19/testing-with-jest-snapshots-first-impressions/&#34;&gt;Testing with Jest Snapshots&lt;/a&gt; - This was my review of &lt;a href=&#34;https://facebook.github.io/jest/&#34;&gt;Jest&lt;/a&gt;&amp;rsquo;s snapshot testing feature.  I found it extremely useful for testing UI components.  I also wrote about Jest again &lt;a href=&#34;http://benmccormick.org/2016/12/10/saving-time-with-jest/&#34;&gt;this month&lt;/a&gt;, transcribing a talk I gave at a local meetup on &lt;a href=&#34;http://benmccormick.org/2016/12/10/saving-time-with-jest/&#34;&gt;How Jest can save you time&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;http://benmccormick.org/2016/01/08/reusable-code-patterns/&#34;&gt;Reusable Code Patterns&lt;/a&gt; - This article was a high level look at the ways you can approach sharing code for 2 different use cases.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;honorable-mention&#34;&gt;Honorable Mention&lt;/h4&gt;
&lt;p&gt;&lt;a href=&#34;http://benmccormick.org/2015/12/30/es6-patterns-converting-callbacks-to-promises/&#34;&gt;ES6 Patterns: Converting Callbacks to Promises&lt;/a&gt; - This article was technically written in 2015, but it was published during the last week of the year and thus wasn&amp;rsquo;t eligible to be included last year. However it has proven quite popular.  This was my attempt at a straightforward explanation of how to convert a callback based API to a Promise based one.&lt;/p&gt;
&lt;h3 id=&#34;code-i-wrote-in-2016&#34;&gt;Code I wrote in 2016&lt;/h3&gt;
&lt;p&gt;Most of the code I wrote this year was for my work at Windsor Circle.  But I have spent some time getting this blog up and running, and anyone interested in what it takes to get a fully functioning blog running on &lt;a href=&#34;https://github.com/gatsbyjs/gatsby&#34;&gt;Gatsby&lt;/a&gt; is welcome to take a look at the &lt;a href=&#34;https://github.com/benmccormick/benmccormickorg&#34;&gt;github repo&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;languages-libraries-and-technologies-i-started-using-in-2016&#34;&gt;Languages, Libraries, and Technologies I started using in 2016&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://facebook.github.io/jest/&#34;&gt;Jest&lt;/a&gt; is a JavaScript testing library that I started using this year. It&amp;rsquo;s fantastic, and I&amp;rsquo;ve had the opportunity to &lt;a href=&#34;http://benmccormick.org/2016/09/19/testing-with-jest-snapshots-first-impressions/&#34;&gt;write&lt;/a&gt; and &lt;a href=&#34;http://benmccormick.org/2016/12/10/saving-time-with-jest/&#34;&gt;speak&lt;/a&gt; about it a few times already.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/gatsbyjs/gatsby&#34;&gt;Gatsbyjs&lt;/a&gt; now powers this blog. Gatsby is a ReactJS based static site generator, and it has been a pleasure to work with.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;My team started using &lt;a href=&#34;https://www.docker.com/&#34;&gt;Docker&lt;/a&gt; this year.  It&amp;rsquo;s been a mixed bag for me personally, but I love the idea of what it provides&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;languages-libraries-and-technologies-i-stopped-using-in-2016&#34;&gt;Languages, Libraries, and Technologies I stopped using in 2016&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Despite my affection for &lt;a href=&#34;http://marionettejs.com/&#34;&gt;Marionette&lt;/a&gt;, I&amp;rsquo;m no longer actively using it other than in some legacy code for my work application&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;languages-and-libraries-i-used-more-or-less-every-day-in-2016&#34;&gt;Languages and Libraries I used (more or less) every day in 2016&lt;/h3&gt;
&lt;p&gt;JavaScript (ES6), Python, React, PostgreSQL, Backbone, lodash&lt;/p&gt;
&lt;h3 id=&#34;languages-and-libraries-i-want-to-try-in-2017&#34;&gt;Languages and Libraries I want to try in 2017&lt;/h3&gt;
&lt;p&gt;RxJS, Flow, VueJS, &lt;a href=&#34;https://github.com/FormidableLabs/victory&#34;&gt;Victory&lt;/a&gt;, Pandas and other python data analysis libraries, Rust&lt;/p&gt;
&lt;h3 id=&#34;blogs-i-started-following-in-2016&#34;&gt;Blogs I started following in 2016&lt;/h3&gt;
&lt;p&gt;Nothing new this year,&lt;/p&gt;
&lt;h3 id=&#34;blogs-i-read-every-post-from-in-2016&#34;&gt;Blogs I read every post from in 2016&lt;/h3&gt;
&lt;p&gt;Rands In Repose, Stratechery, Daring Fireball,  Marco.org, rauchg.com, purposedworking.com&lt;/p&gt;
&lt;h3 id=&#34;podcasts-i-started-listening-to-in-2016&#34;&gt;Podcasts I started listening to in 2016&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;http://www.npr.org/podcasts/510310/npr-politics-podcast&#34;&gt;NPR Politics&lt;/a&gt; - Approachable and fun while still being informative, one of the best ways to follow this years election.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;http://www.npr.org/podcasts/510313/how-i-built-this&#34;&gt;How I Built This&lt;/a&gt; - This has been a great new podcast on entrepreneurship&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;software-i-started-using-in-2016&#34;&gt;Software I started using in 2016&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;http://inbox.google.com&#34;&gt;Google Inbox&lt;/a&gt; + &lt;a href=&#34;http://airmailapp.com/&#34;&gt;Airmail&lt;/a&gt; for email: I&amp;rsquo;m not sure I&amp;rsquo;m ever going to be happy with an email client, but I&amp;rsquo;m currently using the combo of Google Inbox on iOS and Airmail on MacOS.  Post &lt;a href=&#34;https://www.mailboxapp.com/&#34;&gt;Mailbox&lt;/a&gt;, Inbox is my favorite iOS mail app.  On desktop though I like to have universal inbox and tight integration with the rest of the operating system, so I use Airmail, which is less bad than the rest of the MacOS mail clients I&amp;rsquo;ve tried&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;http://copiedapp.com/&#34;&gt;Copied&lt;/a&gt;: Copied is a clipboard manager for MacOS (and sort of iOS).  It&amp;rsquo;s been great to be able to keep multiple things in the clipboard at once, and be able to go back and get something if I blow it away.  I&amp;rsquo;m not a power user.  I haven&amp;rsquo;t really figured out a reason to use their lists features, or their iOS client, but it has been great for the limited things I use it for.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://caskroom.github.io/&#34;&gt;Homebrew Cask&lt;/a&gt;: I&amp;rsquo;ve used homebrew for a while.  But being able to install GUI apps as easily as command line apps has been pretty amazing.  If you are on OSX and don&amp;rsquo;t use homebrew to install pretty much everything, you&amp;rsquo;re missing out.  Of course the real effect is that it makes me dread and hate the Mac App Store even more.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;http://www.nytimes.com/services/mobile/&#34;&gt;The New York Times App&lt;/a&gt;: Ok this is a bit of a cheat since this is more about content than software, but if you&amp;rsquo;re out of touch on what is going on in the world, there&amp;rsquo;s never been a better time to support a good source of news and reporting, whichever outlet is your preference.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;software-i-stopped-using-in-2016&#34;&gt;Software I stopped using in 2016&lt;/h3&gt;
&lt;p&gt;Nothing I&amp;rsquo;m aware of, though I am currently checking out &lt;a href=&#34;http://www.bear-writer.com/&#34;&gt;Bear&lt;/a&gt; and &lt;a href=&#34;https://itunes.apple.com/us/app/annotate-capture-and-share/id918207447?mt=12&#34;&gt;Annotate&lt;/a&gt; as potential replacements for Evernote and Skitch.&lt;/p&gt;
&lt;h3 id=&#34;software-i-used-nearly-every-day-in-2016&#34;&gt;Software I used (nearly) every day in 2016&lt;/h3&gt;
&lt;p&gt;MacOS/iOS, Google Search, Chrome/Safari, Google Inbox/Airmail, Twitter/Tweetbot, Feedbin/Reeder, Instapaper, iMessage, Slack, Trello, 1Password, Atom/Vim, iTerm, Fish Shell, tmux, Bitbucket, Fantastical, Spotify, Evernote, Skitch, Dash&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>What are Higher Order Components?</title>
      <link>https://benmccormick.org/2016/12/14/093000.html</link>
      <pubDate>Wed, 14 Dec 2016 10:30:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2016/12/14/093000.html</guid>
      <description>&lt;p&gt;If you spend much time at all reading through articles and documentation around React, you&amp;rsquo;re likely to run into the term &amp;ldquo;Higher Order component&amp;rdquo;, often abbreviated HoC.  Since it is often used without context in React discussions, and is not a particularly intuitive term for many (most?) developers, I thought it was worth publishing a quick and simple explanation of what Higher Order Components are.&lt;/p&gt;
&lt;p&gt;Higher Order Components are functions that take a React Component, and return a React Component.  The &amp;ldquo;higher order&amp;rdquo; phrasing is borrowed from the term &amp;ldquo;higher order function&amp;rdquo;, a more widely used term in Mathematics and Computer Science that refers to a function that either takes one or more functions as an argument, returns a function, or does both.  Since React Components can be thought of as functions that take data and return ui elements, the naming and usage make sense.  Let&amp;rsquo;s look at an example of a higher order component.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; ExtraPropsComponent &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; (WrappedComponent, componentType) =&amp;gt; {
  &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; ExtraPropsChild &lt;span style=&#34;color:#ff79c6&#34;&gt;extends&lt;/span&gt; React.Component {
    render() {
      &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; props &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;Object&lt;/span&gt;.assign({}, &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.props, {
        importantFunction&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; () =&amp;gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;,
        componentType,
      });
      &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;WrappedComponent {...props}&lt;span style=&#34;color:#ff79c6&#34;&gt;/&amp;gt;&lt;/span&gt;
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is a pretty basic HoC that takes a component and returns a new version of that component that will always be passed 2 extra props &lt;code&gt;importantFunction&lt;/code&gt; and &lt;code&gt;componentType&lt;/code&gt;. One is statically generated in this case, but the other is dynamically passed in when the component is generated.  The ability to pass dynamic content in when defining the component is one of the key wins of HoCs in the real world.  For instance, this is how Redux&amp;rsquo;s &lt;a href=&#34;https://github.com/reactjs/react-redux/blob/master/docs/api.md#connectmapstatetoprops-mapdispatchtoprops-mergeprops-options&#34;&gt;connect&lt;/a&gt; function works.&lt;/p&gt;
&lt;p&gt;Note that this is different from a normal React Component that renders a subcomponent passed as an argument like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; componentType &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;???&amp;#39;&lt;/span&gt;;
&lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; ExtraPropsComponent &lt;span style=&#34;color:#ff79c6&#34;&gt;extends&lt;/span&gt; React.Component
  render() {
      &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; { ChildComponent } &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.props;
      &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; props &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;Object&lt;/span&gt;.assign({}, &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.props, {
        importantFunction&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; () =&amp;gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;,
        componentType,
      });
      &lt;span style=&#34;color:#ff79c6&#34;&gt;delete&lt;/span&gt; props.ChildComponent;

      &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;ChildComponent {...props} &lt;span style=&#34;color:#ff79c6&#34;&gt;/&amp;gt;&lt;/span&gt;;
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;These 2 examples are roughly equivalent for this case, but accomplish things in different ways.  The HoC is a function that takes a component and data when it is created and generates another component.  The normal component example is a component that takes a component as a property and accesses a variable that is in its scope at creation time to generate the element tree that it renders.  The HoC is more flexible as you could theoretically create multiple versions of a component using the single HoC.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;
&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; FancyButton &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; ExtraPropsComponent(Button, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;fancy&amp;#39;&lt;/span&gt;);
&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; CrazyButton &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; ExtraPropsComponent(Button, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;crazy&amp;#39;&lt;/span&gt;);
&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; BoringButton &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; ExtraPropsComponent(Button, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;boring&amp;#39;&lt;/span&gt;);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For the equivalent functionality without using an HoC, you would have to define the whole component for each case.&lt;/p&gt;
&lt;h3 id=&#34;higher-order-components-in-the-real-world&#34;&gt;Higher Order Components in the real world&lt;/h3&gt;
&lt;p&gt;I&amp;rsquo;ve already mentioned connect from &lt;a href=&#34;https://github.com/reactjs/react-redux&#34;&gt;react-redux&lt;/a&gt; as an example of a higher order component.  Other popular libraries that use HoC as part of their APIs include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://formidable.com/open-source/radium/&#34;&gt;Radium&lt;/a&gt;: a library for inline styles in React that uses a higher order component to transform in-line styles added to a component into a more robust-css like system&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/ReactTraining/react-router&#34;&gt;React Router&lt;/a&gt;: a routing library for React that uses &lt;code&gt;withRouter&lt;/code&gt; a HoC that injects access to the router into components that it wraps&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://facebook.github.io/relay/&#34;&gt;Relay&lt;/a&gt;: Facebook&amp;rsquo;s library for connecting to GraphQL APIs includes Relay.Container, a HoC that allows developers to declare the data requirements for a component&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;more-resources&#34;&gt;More Resources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;This was intentionally a very high level look at Higher Order Components.  If you want to go deeper, &lt;a href=&#34;https://medium.com/@franleplant/react-higher-order-components-in-depth-cf9032ee6c3e#.yhbug3ohe&#34;&gt;this medium article&lt;/a&gt; is a great deep dive into all the use cases they allow.&lt;/li&gt;
&lt;li&gt;If you&amp;rsquo;re interested in using HoCs in your own code base, &lt;a href=&#34;https://github.com/acdlite/recompose&#34;&gt;recompose&lt;/a&gt; is a utility library for making the syntax around defining and using them painless&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Readable code: Know your audience </title>
      <link>https://benmccormick.org/2016/12/11/230000.html</link>
      <pubDate>Mon, 12 Dec 2016 00:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2016/12/12/230000.html</guid>
      <description>&lt;p&gt;A coworker asked me last week if there was a better way to write the following python code:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;self&lt;span style=&#34;color:#ff79c6&#34;&gt;.&lt;/span&gt;custom_attributes &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {
  x&lt;span style=&#34;color:#ff79c6&#34;&gt;.&lt;/span&gt;split(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;:&amp;#39;&lt;/span&gt;)[&lt;span style=&#34;color:#bd93f9&#34;&gt;0&lt;/span&gt;]: x&lt;span style=&#34;color:#ff79c6&#34;&gt;.&lt;/span&gt;split(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;:&amp;#39;&lt;/span&gt;)[&lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;]
  &lt;span style=&#34;color:#ff79c6&#34;&gt;for&lt;/span&gt; x &lt;span style=&#34;color:#ff79c6&#34;&gt;in&lt;/span&gt; a&lt;span style=&#34;color:#ff79c6&#34;&gt;.&lt;/span&gt;split(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;,&amp;#39;&lt;/span&gt;)
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I semi-jokingly replied that there were 3 better ways:&lt;/p&gt;
&lt;h5 id=&#34;for-people-who-like-comprehensions&#34;&gt;For people who like comprehensions&lt;/h5&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;self&lt;span style=&#34;color:#ff79c6&#34;&gt;.&lt;/span&gt;custom_attributes &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {
  key: value
  &lt;span style=&#34;color:#ff79c6&#34;&gt;for&lt;/span&gt; [key, value] &lt;span style=&#34;color:#ff79c6&#34;&gt;in&lt;/span&gt; [entry&lt;span style=&#34;color:#ff79c6&#34;&gt;.&lt;/span&gt;split(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;:&amp;#39;&lt;/span&gt;) &lt;span style=&#34;color:#ff79c6&#34;&gt;for&lt;/span&gt; entry &lt;span style=&#34;color:#ff79c6&#34;&gt;in&lt;/span&gt; a&lt;span style=&#34;color:#ff79c6&#34;&gt;.&lt;/span&gt;split(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;,&amp;#39;&lt;/span&gt;)]
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h5 id=&#34;for-people-who-like-functions&#34;&gt;For people who like functions&lt;/h5&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;build_obj&lt;/span&gt;(acc, val):
   [key, value] &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; val&lt;span style=&#34;color:#ff79c6&#34;&gt;.&lt;/span&gt;split(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;:&amp;#39;&lt;/span&gt;)
   acc[key] &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; value
   &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; acc
self&lt;span style=&#34;color:#ff79c6&#34;&gt;.&lt;/span&gt;custom_attributes &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; reduce(build_obj, a&lt;span style=&#34;color:#ff79c6&#34;&gt;.&lt;/span&gt;split(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;,&amp;#39;&lt;/span&gt;), {})
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;for-people-who-like-other-folks-to-be-able-to-read-their-code&#34;&gt;For people who like other folks to be able to read their code&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;# create a hash of custom attributes&lt;/span&gt;
self&lt;span style=&#34;color:#ff79c6&#34;&gt;.&lt;/span&gt;custom_attributes &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {}
&lt;span style=&#34;color:#6272a4&#34;&gt;# get the entries from splitting the input string&lt;/span&gt;
entries &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; a&lt;span style=&#34;color:#ff79c6&#34;&gt;.&lt;/span&gt;split(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;,&amp;#39;&lt;/span&gt;)
&lt;span style=&#34;color:#6272a4&#34;&gt;# for each entry split the key value pairs and add them to the hash&lt;/span&gt;
&lt;span style=&#34;color:#ff79c6&#34;&gt;for&lt;/span&gt; entry &lt;span style=&#34;color:#ff79c6&#34;&gt;in&lt;/span&gt; entries:
   [key, value] &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; entry&lt;span style=&#34;color:#ff79c6&#34;&gt;.&lt;/span&gt;split(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;:&amp;#39;&lt;/span&gt;)
   self&lt;span style=&#34;color:#ff79c6&#34;&gt;.&lt;/span&gt;custom_attributes[key] &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; value
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The joke of course is that it doesn&amp;rsquo;t really matter what the author of the code considers the best way to write it.  Like writing an essay or persuasive speech, it is much more important to consider the audience, and what style will work best for them.  Most code will eventually be read by other people, even if that is simply a future version of the original author who has been stripped of context by time &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;If my coworker is confident that his code will be read in the future by confident Python programmers who understand object comprehensions, then he could go with the first example, with its heavy use of python idioms.  If he thought it was more likely that somebody like me who is used to JavaScript idioms, he might consider the less idiomatic python from the second example that matched his teammates.  If he didn&amp;rsquo;t know who would read the code in the future, he might go with the more explicit and difficult to misinterpret version 3, and possibly tuck it away within a named function so that the main code flow could remain uninterrupted.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;self&lt;span style=&#34;color:#ff79c6&#34;&gt;.&lt;/span&gt;custom_attributes &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; parse_entry_string(a)

&lt;span style=&#34;color:#6272a4&#34;&gt;# ... elsewhere ...&lt;/span&gt;

&lt;span style=&#34;color:#ff79c6&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;parse_entry_string&lt;/span&gt; (entry_string):
    attributes &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {}
    &lt;span style=&#34;color:#6272a4&#34;&gt;# get the entries from splitting the input string&lt;/span&gt;
    entries &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; a&lt;span style=&#34;color:#ff79c6&#34;&gt;.&lt;/span&gt;split(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;,&amp;#39;&lt;/span&gt;)
    &lt;span style=&#34;color:#6272a4&#34;&gt;# for each entry split the key value pairs and add them to the hash&lt;/span&gt;
    &lt;span style=&#34;color:#ff79c6&#34;&gt;for&lt;/span&gt; entry &lt;span style=&#34;color:#ff79c6&#34;&gt;in&lt;/span&gt; entries:
       [key, value] &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; entry&lt;span style=&#34;color:#ff79c6&#34;&gt;.&lt;/span&gt;split(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;:&amp;#39;&lt;/span&gt;)[&lt;span style=&#34;color:#bd93f9&#34;&gt;0&lt;/span&gt;:&lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt;]
       attributes[key] &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; value
    &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; attributes
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Of course once the functionality is separated out into a function, it matters a lot less how it is implemented since the only time somebody will need to read it is when they are interested in that specific functionality and can invest the time to understand the code.  The well named function replaces the need for understanding everything when people browse through the code.  This is extremely important in larger code bases, since data often flows through many lines of code.  The more of it that can be usefully (and accurately) abstracted away for a reader, the easier the code base is to debug.&lt;/p&gt;
&lt;p&gt;So quick tip version:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Think about the audience of the code you&amp;rsquo;re writing&lt;/li&gt;
&lt;li&gt;Naming functions well limits the needs to make implementation details readable for everybody. It can also make your program flow easier to follow.&lt;/li&gt;
&lt;/ol&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;In my experience, it usually only takes about a week for me to look back at my old code and wonder what maniac wrote it and what he could have possibly been thinking&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>Saving Time With Jest: Meetup Summary</title>
      <link>https://benmccormick.org/2016/12/10/001500.html</link>
      <pubDate>Sat, 10 Dec 2016 01:15:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2016/12/10/001500.html</guid>
      <description>&lt;p&gt;This week I gave a talk at the brand new Triangle ReactJS meetup group on how &lt;a href=&#34;https://facebook.github.io/jest/&#34;&gt;Jest&lt;/a&gt; can save developers time.  I was asked afterwards to share the content online for those who missed it.  My talk was mostly demos and wasn&amp;rsquo;t recorded, so there unfortunately isn&amp;rsquo;t much to share, but I thought I could write out the basic ideas behind the talk, and share them here.&lt;/p&gt;
&lt;h3 id=&#34;what-is-jest&#34;&gt;What is Jest&lt;/h3&gt;
&lt;p&gt;Jest is a JavaScript testing framework built by Facebook to address their internal problems testing JavaScript code.  It was open-sourced in 2014, but unlike Facebook&amp;rsquo;s other recent high profile JavaScript OSS projects like React, Flux, Relay and GraphQL, it failed to develop much traction in the community and mostly stagnated for 2 years.  That changed in early 2016 when 2 Facebook developers, &lt;a href=&#34;https://twitter.com/cpojer&#34;&gt;Christoph Pojer&lt;/a&gt; and &lt;a href=&#34;https://twitter.com/abramov_dmitrii&#34;&gt;Dmitrii Abramov&lt;/a&gt; began working on improving the project. Over the past year they&amp;rsquo;ve brought massive improvements to the developer experience of using Jest.&lt;/p&gt;
&lt;p&gt;At a more practical level Jest is a test runner with a built in assertion library and support for code coverage, babel transpilation, and module mocking.  It began as a wrapper around &lt;a href=&#34;https://jasmine.github.io/&#34;&gt;Jasmine&lt;/a&gt;, an older JavaScript testing library, but has since replaced parts of Jasmine with replacement functionality, while retaining backwards compatibility.&lt;/p&gt;
&lt;h3 id=&#34;how-can-jest-save-me-time&#34;&gt;How Can Jest Save Me Time?&lt;/h3&gt;
&lt;p&gt;Jest saves developers  time in 4 main ways:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Setup&lt;/strong&gt; - Jest is simple to configure&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Writing Tests&lt;/strong&gt; - Jest provides a method for writing simple UI tests, and makes it easy to port over existing tests&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Running Tests&lt;/strong&gt; - Jest runs tests in parallel, doesn&amp;rsquo;t require a browser, and only runs the tests that are affected by the current code changes&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Fixing Tests&lt;/strong&gt; - Jest gives great error messages, helps you find the failing code, and has other smaller UX features that make it easy to debug your failing tests quickly.&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote class=&#34;twitter-tweet&#34; data-lang=&#34;en&#34;&gt;&lt;p lang=&#34;en&#34; dir=&#34;ltr&#34;&gt;Tonight &lt;a href=&#34;https://twitter.com/_benmccormick&#34;&gt;@_benmccormick&lt;/a&gt; speaks about using &lt;a href=&#34;https://twitter.com/hashtag/jest?src=hash&#34;&gt;#jest&lt;/a&gt; with &lt;a href=&#34;https://twitter.com/hashtag/reactjs?src=hash&#34;&gt;#reactjs&lt;/a&gt; for your testing needs &lt;a href=&#34;https://twitter.com/nestraleigh&#34;&gt;@nestraleigh&lt;/a&gt; &lt;a href=&#34;https://t.co/CAV8wZUwFw&#34;&gt;pic.twitter.com/CAV8wZUwFw&lt;/a&gt;&lt;/p&gt;&amp;mdash; Tracy Lee | ladyleet (@ladyleet) &lt;a href=&#34;https://twitter.com/ladyleet/status/806655476515618822&#34;&gt;December 8, 2016&lt;/a&gt;&lt;/blockquote&gt;
&lt;h3 id=&#34;setup&#34;&gt;Setup&lt;/h3&gt;
&lt;p&gt;Setting up Jest is extremely straightforward. Here&amp;rsquo;s a &lt;code&gt;Hello World&lt;/code&gt; React Project&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;//package.json
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;{
  &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;simple_example&amp;#34;&lt;/span&gt;,
  &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;version&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;1.0.0&amp;#34;&lt;/span&gt;,
  &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;description&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;A minimal jest testing example&amp;#34;&lt;/span&gt;,
  &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;scripts&amp;#34;&lt;/span&gt;: {
    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;test&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;jest&amp;#34;&lt;/span&gt;
  },
  &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;dependencies&amp;#34;&lt;/span&gt;: {
    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;react&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;^15.4.1&amp;#34;&lt;/span&gt;
  },
  &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;devDependencies&amp;#34;&lt;/span&gt;: {
    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;babel-jest&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;^17.0.2&amp;#34;&lt;/span&gt;,
    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;babel-preset-es2015&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;^6.18.0&amp;#34;&lt;/span&gt;,
    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;babel-preset-react&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;^6.16.0&amp;#34;&lt;/span&gt;,
    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;jest&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;^17.0.3&amp;#34;&lt;/span&gt;,
    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;react-test-renderer&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;^15.4.1&amp;#34;&lt;/span&gt;
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In package.json we have 4 dependencies that are part of a normal React project setup, &lt;code&gt;react&lt;/code&gt;, the 2 babel presets for using &lt;a href=&#34;http://benmccormick.org/2015/09/14/es5-es6-es2016-es-next-whats-going-on-with-javascript-versioning/&#34;&gt;es2015&lt;/a&gt; syntax, and &lt;code&gt;react-test-renderer&lt;/code&gt;, which is a react addon for rendering react for testing, similar to how &lt;code&gt;react-dom&lt;/code&gt; renders components for the browser.  We then add &lt;code&gt;jest&lt;/code&gt; and &lt;code&gt;babel-jest&lt;/code&gt;.  &lt;code&gt;jest&lt;/code&gt; provides the test runner, assertions API, mocking capabilities, and cli.  &lt;code&gt;babel-jest&lt;/code&gt; is a drop-in dependency that lets Jest integrate with Babel.  Neither require any additional configuration in the normal case. Lets say the rest of our project looks like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-txt&#34; data-lang=&#34;txt&#34;&gt;├── __tests__
│   └── simple-component.spec.js
├── package.json
└── simple-component.js
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;// simple-component.js
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; React from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;react&amp;#39;&lt;/span&gt;;

&lt;span style=&#34;color:#ff79c6&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; SimpleComponent &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; () =&amp;gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;div&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;
    Hello World
&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;/div&amp;gt;;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;// __tests__/simple-component.spec.js
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; React from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;react&amp;#39;&lt;/span&gt;;
&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; renderer from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;react-test-renderer&amp;#39;&lt;/span&gt;;
&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; {SimpleComponent} from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;../simple-component&amp;#39;&lt;/span&gt;;

it(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;shows Hello World&amp;#39;&lt;/span&gt;, () =&amp;gt; {
  &lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; component &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; renderer.create( &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;SimpleComponent&lt;span style=&#34;color:#ff79c6&#34;&gt;/&amp;gt;&lt;/span&gt;);
  &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; componentJSON &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; component.toJSON();
  expect(componentJSON.children[&lt;span style=&#34;color:#bd93f9&#34;&gt;0&lt;/span&gt;]).toBe(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Hello World&amp;#39;&lt;/span&gt;);
});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Given this project, we only have to run&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;yarn # or npm install
jest
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and jest will automatically find our test file and run the test.&lt;/p&gt;
&lt;img src=&#34;jest-hello-world.gif&#34; class=&#34;full-width&#34; alt =&#34;gif of running jest&#34;&gt;
&lt;h3 id=&#34;writing-tests&#34;&gt;Writing Tests&lt;/h3&gt;
&lt;p&gt;Jest provides Snapshot Tests, which are a quick way of writing tests to catch changes in the rendered output of a UI component (or any other serializable content).  &lt;a href=&#34;http://benmccormick.org/2016/09/19/testing-with-jest-snapshots-first-impressions/&#34;&gt;I&amp;rsquo;ve written about Snapshot testing before&lt;/a&gt;, so I won&amp;rsquo;t go into depth here.  But snapshot tests are significantly faster to write than traditional assertion based tests, and for the write type of code can provide greater or equal benefit.  This is one area where technically Jest may not save you time.  Instead it may take your team to a place where you&amp;rsquo;re actually willing to write tests for your UI components for the first time.&lt;/p&gt;
&lt;p&gt;There are also a great set of codemods for Jest. &lt;a href=&#34;https://github.com/skovhus/jest-codemods&#34;&gt;jest-codemods&lt;/a&gt; can help you take your existing suite of tests from Mocha, Ava, or tape and translate it over to Jest automatically.  Of course if you were using Jasmine previously, your tests can be migrated without changes. So Jest saves you time by not requiring you to rewrite any tests.&lt;/p&gt;
&lt;h3 id=&#34;running-tests&#34;&gt;Running Tests&lt;/h3&gt;
&lt;p&gt;Jest runs tests fast by default.  While I&amp;rsquo;ve seen from comments on my last Jest post and elsewhere that some people may have been able to optimize mocha or AVA to be fast enough that switching to Jest was a downgrade, for most people Jest is going to be faster than whatever they may have been using before.  This is true because of performance reasons (tests run in parallel, and mock out timers to avoid unnecessary waiting), but also because of UX decisions.  Jest is able to use git and node&amp;rsquo;s modules system to detect what files have changed since the last commit, and which tests are affected by that.  Because of that, it is able to optionally run only the tests that might have changed on each run (&lt;code&gt;jest -o&lt;/code&gt;).  Since it is usually able to run tests fast as a result (since it only runs a few at a time), Jest also is able to have an awesome watch mode (&lt;code&gt;jest --watch&lt;/code&gt;).  In watch mode, tests rerun as files change, and there are options to target specific tests, run all tests, or fix snapshots as you go.&lt;/p&gt;
&lt;img src=&#34;jest-watch.gif&#34; class=&#34;full-width&#34; alt =&#34;gif of running jest --watch&#34;&gt;
&lt;h3 id=&#34;fixing-tests&#34;&gt;Fixing Tests&lt;/h3&gt;
&lt;p&gt;Jest provides 4 main conveniences for fixing tests&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Error messages have clear formatted diffs, making it easy to know the difference between what was received and expected&lt;/li&gt;
&lt;li&gt;Error messages have a clear traceback to the line that failed, either the assertion in the test file, or the exception in the source file&lt;/li&gt;
&lt;li&gt;Even though tests run in parallel, Jest makes sure that any console output from the test is placed in line with the test output, making it easy to debug with quick console messages&lt;/li&gt;
&lt;li&gt;When running Jest multiple times, Jest runs the tests that failed in the previous run prior to other tests, leading to a faster feedback loop even when not using watch mode&lt;/li&gt;
&lt;/ol&gt;
&lt;img src=&#34;jest-error.png&#34; class=&#34;full-width&#34; alt =&#34;gif of running jest --watch&#34;&gt;
&lt;h3 id=&#34;more-resources&#34;&gt;More Resources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Another speakup at Wednesday&amp;rsquo;s meetup has a Jest related blog post out this week.  Nate Hunzaker blogged about &lt;a href=&#34;https://www.viget.com/articles/acceptance-testing-react-apps-with-jest-and-nightmare&#34;&gt;using Jest with Nightmare.js for acceptance tests&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If you live in the Triangle area (thats Raleigh/Durham, North Carolina to the rest of the world) make sure to check out the &lt;a href=&#34;http://www.meetup.com/trianglereact/&#34;&gt;Triangle React meetup&lt;/a&gt;.  The plan as I understand it is to do events once a month, alternating project nights and talks.  I believe &lt;a href=&#34;https://twitter.com/ladyleet&#34;&gt;Tracy&lt;/a&gt; is looking for more speakers too, so hit her up if you&amp;rsquo;re interested.  This time 4 of us spoke for 15-20 minutes, so it isn&amp;rsquo;t as much preparation as other events where you&amp;rsquo;re the only speaker.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>A whole new site</title>
      <link>https://benmccormick.org/2016/12/02/110000.html</link>
      <pubDate>Fri, 02 Dec 2016 12:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2016/12/02/110000.html</guid>
      <description>&lt;p&gt;After 2.5 years of stability, this week I moved benmccormick.org to a new platform and overhauled the look and feel. Although most readers have seen the site remain relatively stable, this is actually the 5th major revision of the site since it was first created, so this seems like a good time for a quick trip down memory lane.&lt;/p&gt;
&lt;p&gt;I first started it as a Django app, wanting to challenge myself to build a blog.  That was so short-lived that the way-back machine never even registered it, and I don&amp;rsquo;t have any evidence that it ever existed (thankfully).  In December 2012, I moved the blog over to &lt;a href=&#34;http://octopress.org/&#34;&gt;Octopress&lt;/a&gt; a static site generator based on Ruby.  I started out using a very nice stock template:&lt;/p&gt;
&lt;img src=&#34;oldsite1.png&#34; class=&#34;full-width&#34;&gt;
&lt;p&gt;and then shortly switched to a version that I mostly did myself based off of the default octopress theme.  This was one of my first attempts to design anything from scratch, and was not particularly pretty:&lt;/p&gt;
&lt;img src=&#34;oldsite2.png&#34; class=&#34;full-width&#34;&gt;
&lt;p&gt;I enjoyed Octopress, but spent a lot of time messing around with it (and struggling through the unfamiliar ruby ecosystem), and not a lot of time writing.  So in the spring of 2014 I decided I wanted to switch to a blogging platform where I could write, rather than messing with code.  So I moved my blog to &lt;a href=&#34;https://ghost.org/&#34;&gt;Ghost&lt;/a&gt;, lightly modified a public theme, and began writing about Vim.  It was around this time (2 years and 40 articles in) that I began to attract more readers, and also began to focus more on higher quality technical articles:&lt;/p&gt;
&lt;img src=&#34;oldsite3.png&#34; class=&#34;full-width&#34;&gt;
&lt;p&gt;About a year after that I re-introduced some color to the blog after a prolonged absence. The black and white sidebar was traded for a colorful green, and a I began using a mix of blue and red for text emphasis. I also began to focus on making it more clear how to subscribe to the blog, and highlighted the more popular content:&lt;/p&gt;
&lt;img src=&#34;oldsite4.png&#34; class=&#34;full-width&#34;&gt;
&lt;p&gt;Ghost was a great blogging platform, but this fall I decided it was time to move off of it.  I was interested in trying some things that didn&amp;rsquo;t fit into the platform&amp;rsquo;s more structured approach, and wanted to move the blog to a place where it was no longer losing me money to run.  So I decided to take another look at the static site generator landscape. I looked through the top 12 or so options on &lt;a href=&#34;https://www.staticgen.com/&#34;&gt;StaticGen&lt;/a&gt; and &lt;a href=&#34;https://github.com/gatsbyjs/gatsby&#34;&gt;Gatsby&lt;/a&gt; quickly stood out.  It uses concepts I&amp;rsquo;m extremely comfortable with (built with React and Webpack!), produces fast server-rendered SPA style sites, and dictates almost nothing about how the site is built.&lt;/p&gt;
&lt;p&gt;The site is now built with Gatsby and hosted on Github pages.  I&amp;rsquo;ve ditched the noisy green sidebar in favor of a simpler text-focused experience and added a small ad at the top of the page to offset some of the costs associated with the blog.  I&amp;rsquo;m planning on iterating on the design (better organizing and exposing older content, making it simpler to subscribe to the blog, and making it easier for me to add rich content/code examples to posts without relying on 3rd party services), but for right now I&amp;rsquo;m excited to get back to focusing on writing.&lt;/p&gt;
&lt;img src=&#34;current_site.png&#34; class=&#34;full-width&#34;&gt;
&lt;p&gt;Like all software, as this blog has evolved, I&amp;rsquo;m sure not all of the progress has been forward.  If you see any issues with the new site, feedback and bugfixes are welcome.  Feel free to hit me up on &lt;a href=&#34;https://twitter.com/_benmccormick&#34;&gt;twitter&lt;/a&gt;, comment on this post, or open an issue on the site&amp;rsquo;s &lt;a href=&#34;https://github.com/benmccormick/benmccormickorg/issues&#34;&gt;github repo&lt;/a&gt;.  Thank you to everyone who has read and supported this site over the past several years.&lt;/p&gt;
&lt;h3 id=&#34;more-resources&#34;&gt;More Resources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;If you&amp;rsquo;re interested in &lt;a href=&#34;https://github.com/gatsbyjs/gatsby&#34;&gt;Gatsby&lt;/a&gt; this post on &lt;a href=&#34;https://blog.scottnonnenberg.com/practical-gatsby-js/&#34;&gt;Practical Gatsby.js&lt;/a&gt; by Scott Nonnenberg is excellent.  Its not a how-to, but more of a series of examples of how he deviated from the base Gatsby blog (and why).  I found it really helpful when brainstorming ideas for this site.&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Testing with Jest Snapshots: First Impressions</title>
      <link>https://benmccormick.org/2016/09/19/074100.html</link>
      <pubDate>Mon, 19 Sep 2016 08:41:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2016/09/19/074100.html</guid>
      <description>&lt;p&gt;Over the past 6 months my team at work has been slowly transitioning a large Backbone application to React.  One of the main goals of the transition has been to build out unit tests as we transition components.  As part of that we switched from using Karma to using Jest for managing our tests.&lt;/p&gt;
&lt;p&gt;Our new setup with Jest has several advantages over our previous setup. All Jest tests run through node using a fake DOM implementation.  We don&amp;rsquo;t need to start up a browser so tests are faster and less flaky &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.  Jest makes it possible to mock all modules by default &lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;, which works well for us since our code base currently contains a large amount of code that is difficult to test for one reason or another.  Jest provides great integration with Babel, which is helpful since all of our Backbone and React code uses ES6 that we transpile for the browser.  Finally Jest provides a wonderful watch mode that runs only the tests that are relevant to the changes you&amp;rsquo;ve made and makes it easy to see the result.&lt;/p&gt;
&lt;p&gt;About a month ago, Jest debuted a new feature: Snapshot testing.  It works a bit differently than a normal unit test.  Instead of executing some code and comparing the output against a value provided by a developer, the first time a test is run, the output passed into the test is saved to a &amp;ldquo;snapshot file&amp;rdquo;.  Then when the test is run in the future, the output is compared to the snapshot file.  If the output matches the file, the test passes, if the output is different then the file, the test fails and Jest prints a diff.  We&amp;rsquo;ve been using Jest snapshots for a few weeks now and I wanted to share my initial impressions.&lt;/p&gt;
&lt;h3 id=&#34;what-is-it-like-to-use-a-snapshot-test-&#34;&gt;What is it like to use a snapshot test ?&lt;/h3&gt;
&lt;p&gt;The process for snapshot testing is a bit different than normal tests.  Most snapshot tests look fairly simple.  Something like this example from the &lt;a href=&#34;https://github.com/facebook/jest/tree/master/examples/snapshot&#34;&gt;Jest repository&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;// Link.react.js
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;// Copyright 2004-present Facebook. All Rights Reserved.
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;
&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; React from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;react&amp;#39;&lt;/span&gt;;

&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; STATUS &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {
  NORMAL&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;normal&amp;#39;&lt;/span&gt;,
  HOVERED&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;hovered&amp;#39;&lt;/span&gt;,
};

&lt;span style=&#34;color:#ff79c6&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;default&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; Link &lt;span style=&#34;color:#ff79c6&#34;&gt;extends&lt;/span&gt; React.Component {

  constructor() {
    &lt;span style=&#34;color:#ff79c6&#34;&gt;super&lt;/span&gt;();

    &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;._onMouseEnter &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;._onMouseEnter.bind(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;);
    &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;._onMouseLeave &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;._onMouseLeave.bind(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;);

    &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.state &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {
      &lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; STATUS.NORMAL,
    };
  }

  _onMouseEnter() {
    &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.setState({&lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; STATUS.HOVERED});
  }

  _onMouseLeave() {
    &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.setState({&lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; STATUS.NORMAL});
  }

  render() {
    &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; (
      &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;a
        className&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;{&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.state.&lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt;}
        href&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;{&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.props.page &lt;span style=&#34;color:#ff79c6&#34;&gt;||&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;#&amp;#39;&lt;/span&gt;}
        onMouseEnter&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;{&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;._onMouseEnter}
        onMouseLeave&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;{&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;._onMouseLeave}&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;
        {&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.props.children}
      &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;/a&amp;gt;
    );
  }

}

&lt;span style=&#34;color:#6272a4&#34;&gt;// Link.react-test.js  (partial)
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;// Copyright 2004-present Facebook. All Rights Reserved.
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;/* eslint-disable no-unused-vars */&lt;/span&gt;

&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;use strict&amp;#39;&lt;/span&gt;

&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; React from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;react&amp;#39;&lt;/span&gt;;
&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; Link from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;../Link.react&amp;#39;&lt;/span&gt;;
&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; renderer from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;react-test-renderer&amp;#39;&lt;/span&gt;;

it(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;renders correctly&amp;#39;&lt;/span&gt;, () =&amp;gt; {
  &lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; tree &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; renderer.create(
    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;Link page&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;http://www.facebook.com&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;Facebook&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;/Link&amp;gt;
  ).toJSON();
  expect(tree).toMatchSnapshot();
});

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The first time the test is run, a snapshot file is produced.  In this case, running the previous test produces a snapshot file that looks like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;// Link.react-test.js.snap  (partial)
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;exports[&lt;span style=&#34;color:#f1fa8c&#34;&gt;`test renders correctly 1`&lt;/span&gt;] &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;`
&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;lt;a
&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;  className=&amp;#34;normal&amp;#34;
&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;  href=&amp;#34;http://www.facebook.com&amp;#34;
&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;  onMouseEnter={[Function bound _onMouseEnter]}
&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;  onMouseLeave={[Function bound _onMouseLeave]}&amp;gt;
&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;  Facebook
&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;lt;/a&amp;gt;
&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;`&lt;/span&gt;;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This gives us a baseline for what we expect the UI to look like.  The snapshot is generated in a folder in your &lt;code&gt;__tests__&lt;/code&gt; directory, so that it can be checked into source control.&lt;/p&gt;
&lt;p&gt;The next time a test is run, if nothing has changed, the test passes.  However, if we change something (let&amp;rsquo;s say we add a class), the test fails and shows us a diff.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;// updated link render method
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;
render() {
  &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; (
    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;a
      className&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;{&lt;span style=&#34;color:#f1fa8c&#34;&gt;`link-item &lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.state.&lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;`&lt;/span&gt;}
      href&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;{&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.props.page &lt;span style=&#34;color:#ff79c6&#34;&gt;||&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;#&amp;#39;&lt;/span&gt;}
      onMouseEnter&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;{&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;._onMouseEnter}
      onMouseLeave&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;{&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;._onMouseLeave}&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;
      {&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.props.children}
    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;/a&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-diff&#34; data-lang=&#34;diff&#34;&gt;
# jest output

FAIL  __tests__/Link.react-test.js
 ✕ renders correctly (16ms)

● renders correctly

    Received value does not match the stored snapshot 1.

    - Snapshot
    + Received

      &amp;lt;a
&lt;span style=&#34;color:#f55&#34;&gt;-       className=&amp;#34;normal&amp;#34;
&lt;/span&gt;&lt;span style=&#34;color:#f55&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#50fa7b;font-weight:bold&#34;&gt;+       className=&amp;#34;link-item normal&amp;#34;
&lt;/span&gt;&lt;span style=&#34;color:#50fa7b;font-weight:bold&#34;&gt;&lt;/span&gt;        href=&amp;#34;http://www.facebook.com&amp;#34;
        onMouseEnter={[Function bound _onMouseEnter]}
        onMouseLeave={[Function bound _onMouseLeave]}&amp;gt;
        Facebook
      &amp;lt;/a&amp;gt;

      at Object.&amp;lt;anonymous&amp;gt; (__tests__/Link.react-test.js:14:16)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We can then choose to accept this change by running &lt;code&gt;jest -u&lt;/code&gt; to update the snapshot, or update our code to fix the regression.  If we update the snapshot file, the test will start passing again.&lt;/p&gt;
&lt;h3 id=&#34;snapshot-tests-are-a-complement-for-conventional-tests-not-a-replacement&#34;&gt;Snapshot tests are a complement for conventional tests not a replacement&lt;/h3&gt;
&lt;p&gt;The first thing that became clear to me while using snapshot testing is that they&amp;rsquo;re not for everything.  They are optimized for a different case than normal assertion-based tests.&lt;/p&gt;
&lt;p&gt;Classic assertion based tests are perfect for testing clearly defined behavior that is expected to remain relatively stable.&lt;/p&gt;
&lt;p&gt;Snapshot tests are great for testing less clearly defined behavior that may change often.&lt;/p&gt;
&lt;p&gt;Snapshot testing is perfect for things that in the past would have raised concern for &amp;ldquo;overly brittle&amp;rdquo; tests that slow development teams down.  The classic example of this (and the main focus of discussion around Jest snapshots so far) is UI testing.&lt;/p&gt;
&lt;p&gt;UI components often change in small and trivial ways.  Copy is changed, whitespace is added, a border color is modified. Generally this means that developers have to choose between detailed tests that catch any regression but require constant updates, or less detailed tests that focus on core behaviors but miss smaller regressions.&lt;/p&gt;
&lt;p&gt;Snapshot tests provide a new way of approaching these problems in unit tests.  Because they are easy to write and effortless to update, and provide a clear view of what changed after each update, whether it is major or minor.&lt;/p&gt;
&lt;p&gt;This isn&amp;rsquo;t without any disadvantage. Snapshot tests preserve a starting point, but don&amp;rsquo;t give any indication of developer intent to future developers.  Like any other test, if the initial snapshot passes with bugs, or doesn&amp;rsquo;t capture the full range of cases, the test won&amp;rsquo;t adequately cover those behaviors.  But unlike traditional tests, snapshot tests don&amp;rsquo;t provide specific guidance for what the original developer expected beyond the &amp;ldquo;actual behavior&amp;rdquo;.  If there are multiple sub-behaviors that interact to produce output, its not clear which of those are essential, and which are incidental.  That&amp;rsquo;s not something you want for your critical application logic, especially complicated logic with many subtle cases.  But for UI components and other application elements that are likely to change a lot over time, this is a good set of tradeoffs.&lt;/p&gt;
&lt;h3 id=&#34;snapshot-tests-are-more-useful-with-a-healthy-code-review-process&#34;&gt;Snapshot tests are more useful with a healthy code review process&lt;/h3&gt;
&lt;p&gt;I&amp;rsquo;ve pointed out several times now that snapshot tests are easy to update.  One of the downsides of the current design is that they can be almost too easy to update.  When a snapshot test fails, you have the option of modifying the output so that the test passes again, or updating the snapshot to reflect the new output.  Unfortunately, Jest currently provides no granularity for this updating.  Running &lt;code&gt;jest -u&lt;/code&gt; to update the snapshots will update all snapshots.  So if  a single change causes many snapshots to break, it can be easy to accidentally update all of them, and possibly difficult to work through the whole diff to find changes.&lt;/p&gt;
&lt;p&gt;A robust code review process minimizes these problems.  Because snapshots are checked into source, the diffs in the snapshots are checked into source control.  Viewing diffs in a dedicated code review tool like Github, Bitbucket or Gitlab, it&amp;rsquo;s easier to see exactly what changed over many files than it might be when updating snapshots from the command line, and if you update a snapshot multiple times in a single branch, you can see the net effect on the snapshot through source control diffs better than you can through Jest.&lt;/p&gt;
&lt;h3 id=&#34;snapshot-tests-work-well-with-auto-mocking&#34;&gt;Snapshot tests work well with auto-mocking&lt;/h3&gt;
&lt;p&gt;Auto-mocking has been one of Jest&amp;rsquo;s more controversial features.  Prior to version 15, Jest mocked every module used in tests by default.  To run the actual module code, it was necessary to manually unmock each module used or change Jest configurations.  Though it is now disabled by default, auto-mocking actually works very well with snapshot tests.  One problem with tests that rely on generating DOM in React is the fact that most components of any complexity are actually made up of smaller components, that often use external functions with complex logic to determine what to show.  If we fully render everything, changing any of those pieces can break tests for many components, moving us away from the concept of a &amp;ldquo;unit test&amp;rdquo;.  If we mock child components and helper functions and then test them individually though, we can focus our tests to only change based on the logic of the individual component being tested.  This is incredibly easy with Jest, and especially helpful in large code bases that don&amp;rsquo;t have complete test coverage.  Auto-mocking is considered an &amp;ldquo;advanced feature&amp;rdquo; of Jest, but it&amp;rsquo;s not hard to use.  Most mocked modules produce something non-harmful by default, and when its necessary to override, its not difficult to produce something meaningful without getting too involved.  Just add a file with the same name as the file to be mocked into a &lt;code&gt;__mocks__&lt;/code&gt; folder in that directory, and give the mocked module the same interface as the mocked component.  You can either write it from scratch or use &lt;a href=&#34;http://facebook.github.io/jest/docs/api.html#jest-genmockfrommodule-modulename&#34;&gt;jest.genMockFromModule&lt;/a&gt; as a starting place.&lt;/p&gt;
&lt;h3 id=&#34;summary&#34;&gt;Summary&lt;/h3&gt;
&lt;p&gt;I&amp;rsquo;m impressed by Jest snapshots.  When combined with React, they&amp;rsquo;re providing my first non-frustrating experience unit testing UI components.  I&amp;rsquo;m excited to use them more going forward, and will be interested to see how they evolve from here.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&#34;extra-a-few-miscellaneous-jest-thoughts&#34;&gt;Extra: A few miscellaneous Jest Thoughts&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The UI output from Jest 15 tests is the best I&amp;rsquo;ve ever seen from a testing framework.  Aside from the nice diffs on snapshots, they do a good job explaining how output differed from expectations in assertion based tests, and communicating context for test failures, warnings and logging messages.  They also give great guidance when making configuration changes:&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote class=&#34;twitter-tweet&#34; data-lang=&#34;en&#34;&gt;&lt;p lang=&#34;en&#34; dir=&#34;ltr&#34;&gt;&lt;a href=&#34;https://twitter.com/cpojer&#34;&gt;@cpojer&lt;/a&gt; This is lovely, thank you! &lt;a href=&#34;https://t.co/CX1v11CAVc&#34;&gt;pic.twitter.com/CX1v11CAVc&lt;/a&gt;&lt;/p&gt;&amp;mdash; Ben McCormick (@_benmccormick) &lt;a href=&#34;https://twitter.com/_benmccormick/status/772906536154894336&#34;&gt;September 5, 2016&lt;/a&gt;&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;I&amp;rsquo;ve also been super impressed with Jest&amp;rsquo;s watch mode in Jest 15.  &lt;code&gt;--watch&lt;/code&gt; makes it easy to focus on a few files or run tests on all files, and stays up to date as you change code.  If you haven&amp;rsquo;t worked with Jest in a while, the developer experience alone makes it worth trying out.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;One potential future annoyance with snapshot tests:  The snapshot format can&amp;rsquo;t be iterated on without breaking all current tests.  Make sure not to mix functional changes with Jest updates!&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote class=&#34;twitter-tweet&#34; data-cards=&#34;hidden&#34; data-lang=&#34;en&#34;&gt;&lt;p lang=&#34;en&#34; dir=&#34;ltr&#34;&gt;We&amp;#39;ll update the snapshot format sometimes in minor/major releases. When updating Jest, please update snapshots&lt;br&gt;&lt;br&gt;See &lt;a href=&#34;https://t.co/gPE63dMz8P&#34;&gt;https://t.co/gPE63dMz8P&lt;/a&gt;&lt;/p&gt;&amp;mdash; Christoph Pojer (@cpojer) &lt;a href=&#34;https://twitter.com/cpojer/status/776623521069805568&#34;&gt;September 16, 2016&lt;/a&gt;&lt;/blockquote&gt;
&lt;h3 id=&#34;more-resources&#34;&gt;More Resources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Randy Coulman has a &lt;a href=&#34;http://randycoulman.com/blog/2016/09/06/snapshot-testing-use-with-care/&#34;&gt;nice article&lt;/a&gt; on some of the reasons to be careful about embracing snapshot testing.  He makes good points about the requirement of human involvement in verifying a change in time-crunched situations and also the potential value of snapshot tests for legacy code.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;My team uses a mix of &lt;a href=&#34;https://github.com/airbnb/enzyme&#34;&gt;enzyme&lt;/a&gt; and snapshot tests for unit testing React Components.  &lt;a href=&#34;https://github.com/trayio/enzyme-to-json?utm_content=buffer6b78b&amp;amp;utm_medium=social&amp;amp;utm_source=twitter.com&amp;amp;utm_campaign=buffer&#34;&gt;This repo&lt;/a&gt; combines them, allowing you to use enzyme to generate the snapshot output to diff against rather than the renderer provided by Jest. I personally haven&amp;rsquo;t felt the need to integrate these two tools, but if your team uses enzyme and wants consistency/fewer (used) dependencies, this could be a cool option.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Finally here&amp;rsquo;s &lt;a href=&#34;https://blog.grommet.io/post/2016/09/01/how-we-landed-on-jest-snapshot-testing-for-javascript&#34;&gt;another article&lt;/a&gt; on how Snapshot testing convinced one team to migrate to Jest from Tape&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;PhantomJS was a tremendous source of pain in our Karma setup.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;This used to be the default setting, with Jest 15 it can be configured to work that way.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>Quick Tip: Take advantage of lodash collections</title>
      <link>https://benmccormick.org/2016/06/26/162755.html</link>
      <pubDate>Sun, 26 Jun 2016 17:27:55 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2016/06/26/162755.html</guid>
      <description>&lt;p&gt;One of the more frustrating things about using JavaScript in the browser is the number of different collection types that you need to deal with.  When using native APIs and 3rd party libraries, it&amp;rsquo;s easy to encounter 3 or more different types of collections, including &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/API/NodeList&#34;&gt;NodeLists&lt;/a&gt;, &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/API/HTMLCollection&#34;&gt;HTMLCollections&lt;/a&gt;, &lt;a href=&#34;https://learn.jquery.com/using-jquery-core/jquery-object/&#34;&gt;jQuery Objects&lt;/a&gt;, and plain arrays.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; a &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;document&lt;/span&gt;.querySelectorAll(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;div&amp;#39;&lt;/span&gt;)
a instanceOf NodeList &lt;span style=&#34;color:#6272a4&#34;&gt;//true
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; b &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;document&lt;/span&gt;.getElementsByTagName(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;div&amp;#39;&lt;/span&gt;)
b instanceOf HTMLCollection &lt;span style=&#34;color:#6272a4&#34;&gt;//true
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; c &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; $(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;div&amp;#39;&lt;/span&gt;)
c instanceOf jQuery &lt;span style=&#34;color:#6272a4&#34;&gt;// true
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; d &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; [&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;button1&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;button2&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;button3&amp;#39;&lt;/span&gt;].map(id =&amp;gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;document&lt;/span&gt;.getElementById(id));
d instance &lt;span style=&#34;color:#ff79c6&#34;&gt;of&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;Array&lt;/span&gt; &lt;span style=&#34;color:#6272a4&#34;&gt;//true
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This ends up mattering in practice because not every function that is available on Array is available on NodeList, HTMLCollections, and jQuery objects.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; ids &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;document&lt;/span&gt;.querySelectorAll(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;div&amp;#39;&lt;/span&gt;).map(el =&amp;gt; el.id)
&lt;span style=&#34;color:#6272a4&#34;&gt;// Uncaught TypeError: document.querySelectorAll(...).map is not a function
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;
ids &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;document&lt;/span&gt;.getElementsByTagName(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;div&amp;#39;&lt;/span&gt;).map(el =&amp;gt; el.id)
&lt;span style=&#34;color:#6272a4&#34;&gt;// Uncaught TypeError: document.getElementsByTagName(...).map is not a function
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; numDivs &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; $(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;div&amp;#39;&lt;/span&gt;).reduce((count, el) =&amp;gt; count &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;, &lt;span style=&#34;color:#bd93f9&#34;&gt;0&lt;/span&gt;);
&lt;span style=&#34;color:#6272a4&#34;&gt;// Uncaught TypeError: $(...).reduce is not a function
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Since we can&amp;rsquo;t use native array methods on these alternate collections, we end up having to be very careful about knowing where we&amp;rsquo;ve retrieved data from, and how to convert those collections or how to work around their limitations.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s useful to know about these distinctions, but in practice dealing with them is a pain.  One of the nice properties of &lt;a href=&#34;https://lodash.com/docs&#34;&gt;lodash&lt;/a&gt; is that it abstracts over these incompatibilities.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; ids &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; _.map(&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;document&lt;/span&gt;.querySelectorAll(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;div&amp;#39;&lt;/span&gt;), el =&amp;gt; el.id);
&lt;span style=&#34;color:#6272a4&#34;&gt;// [&amp;#39;container&amp;#39;, &amp;#39;left-box&amp;#39;, &amp;#39;right-box&amp;#39;]
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;
ids &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; _.map(&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;document&lt;/span&gt;.getElementssByTagName(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;div&amp;#39;&lt;/span&gt;), el =&amp;gt; el.id);
&lt;span style=&#34;color:#6272a4&#34;&gt;// [&amp;#39;container&amp;#39;, &amp;#39;left-box&amp;#39;, &amp;#39;right-box&amp;#39;]
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; numDivs &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; _.reduce($(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;div&amp;#39;&lt;/span&gt;), (count, el) =&amp;gt; count &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;, &lt;span style=&#34;color:#bd93f9&#34;&gt;0&lt;/span&gt;));
&lt;span style=&#34;color:#6272a4&#34;&gt;// 3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For methods that iterate over a collection lodash treats all array-like objects (essentially anything with a length property) the same and iterates over their numerical properties from 0 to length-1.  This provides a nice consistency when working with DOM APIs and removes the mental overhead from managing their inconsistencies.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>What are mutable and immutable data structures?</title>
      <link>https://benmccormick.org/2016/06/04/165252.html</link>
      <pubDate>Sat, 04 Jun 2016 17:52:52 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2016/06/04/165252.html</guid>
      <description>&lt;p&gt;t
Sometimes concepts and ideas slowly grow in a programming community, sometimes they seem to appear in a flash.  For the first several years I wrote JavaScript, I don&amp;rsquo;t recall ever seeing anything written online about immutable data.  Since React hit the scene in the last 2 years however, articles mentioning mutable and immutable data seem to have multiplied, as have libraries like Immutable.js and alternate front end languages like Elm that allow users to &amp;ldquo;use immutable data&amp;rdquo;.  I&amp;rsquo;m not going to address those libraries, but thought it would be useful to throw out a quick primer on what immutable data actually is, how it differs from mutable data, and why anyone cares.&lt;/p&gt;
&lt;p&gt;A mutable object is an object whose state can be modified after it is created.  An immutable object is an object whose state cannot be modified after it is created.  Examples of native JavaScript values that are immutable are numbers and strings.  Examples of native JavaScript values that are mutable include objects, arrays, functions, classes, sets, and maps.&lt;/p&gt;
&lt;h3 id=&#34;implications-of-mutable-objects&#34;&gt;Implications of mutable objects&lt;/h3&gt;
&lt;p&gt;So why does this matter?  Consider the following code examples:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; a &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {
    foo&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;
};

&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; b &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; a;

a.foo &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;test&amp;#39;&lt;/span&gt;;

console.log(b.foo); &lt;span style=&#34;color:#6272a4&#34;&gt;// test
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;console.log(a &lt;span style=&#34;color:#ff79c6&#34;&gt;===&lt;/span&gt; b) &lt;span style=&#34;color:#6272a4&#34;&gt;// true
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; a &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;test&amp;#39;&lt;/span&gt;;
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; b &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; a;
a &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; a.substring(&lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt;);

console.log(a) &lt;span style=&#34;color:#6272a4&#34;&gt;//st
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;console.log(b) &lt;span style=&#34;color:#6272a4&#34;&gt;//test
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;console.log(a &lt;span style=&#34;color:#ff79c6&#34;&gt;===&lt;/span&gt; b) &lt;span style=&#34;color:#6272a4&#34;&gt;//false
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; a &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; [&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;];
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; b &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; a;

a.push(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;)

console.log(b); &lt;span style=&#34;color:#6272a4&#34;&gt;// [&amp;#39;foo&amp;#39;, &amp;#39;bar&amp;#39;, &amp;#39;baz&amp;#39;]
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;console.log(a &lt;span style=&#34;color:#ff79c6&#34;&gt;===&lt;/span&gt; b) &lt;span style=&#34;color:#6272a4&#34;&gt;// true
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; a &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;;
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; b &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; a;
a&lt;span style=&#34;color:#ff79c6&#34;&gt;++&lt;/span&gt;;

console.log(a) &lt;span style=&#34;color:#6272a4&#34;&gt;//2
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;console.log(b) &lt;span style=&#34;color:#6272a4&#34;&gt;//1
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;console.log(a &lt;span style=&#34;color:#ff79c6&#34;&gt;===&lt;/span&gt; b) &lt;span style=&#34;color:#6272a4&#34;&gt;//false
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;What we see is that for mutable values, updating state applies across all &lt;em&gt;references&lt;/em&gt; to that variable.  So changing a value in one place, changes it for all references to that object.  For the immutable data types, we have no way of changing the internal state of the data, so the reference always gets reassigned to a new object.  The biggest implication of this is that for immutable data, equality is more reliable since we know that a value&amp;rsquo;s state won&amp;rsquo;t be changed out from under us.&lt;/p&gt;
&lt;p&gt;Finally, its worth noting that it&amp;rsquo;s still possible to treat JavaScript objects as immutable.  This can first be done through &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze&#34;&gt;Object.freeze&lt;/a&gt;, which shallowly renders a JavaScript object immutable.  But it can also be done with programmer discipline.  If we want to rely on object&amp;rsquo;s being immutable, it&amp;rsquo;s possible to enforce that all object updates are done through something like
&lt;code&gt;Object.assign(a, {foo: &#39;bar&#39;})&lt;/code&gt; rather than &lt;code&gt;a.foo = &#39;bar&#39;&lt;/code&gt;, and all array updates are done through functions that generate new arrays like &lt;code&gt;Array.prototype.map&lt;/code&gt;, &lt;code&gt;Array.prototype.filter&lt;/code&gt;, or &lt;code&gt;Array.prototype.concat&lt;/code&gt;, rather than mutating methods like &lt;code&gt;Array.prototype.push&lt;/code&gt;, &lt;code&gt;Array.prototye.pop&lt;/code&gt;, or &lt;code&gt;Array.prototype.sort&lt;/code&gt;.  This is less reliable without language level constraints, but has become popular in the React ecosystem for dealing with data for folks who don&amp;rsquo;t want to introduce abstractions like Immutable.js.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Digging Into React: Choosing Component Styles</title>
      <link>https://benmccormick.org/2016/05/01/213236.html</link>
      <pubDate>Sun, 01 May 2016 22:32:36 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2016/05/02/213236.html</guid>
      <description>&lt;p&gt;Over the past month I’ve been building my first production features using React.  One of the first things I’ve noticed is the amount of choices that come into a new React project.  A lot of this is about the ecosystem around React (Webpack vs Browserify? Redux vs Relay? Do I need CSS modules or Immutable.js?) but many of the choices are just part of the library, figuring out the best, or at least a consistent, way to do things.&lt;/p&gt;
&lt;p&gt;One such choice is the syntax for defining components that you choose to use.  In React, you can define components in at least 3 different styles: the React.createClass style, the ES6 class style, and the pure functional style &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;. Each has some advantages and disadvantages.&lt;/p&gt;
&lt;h3 id=&#34;reactcreateclass&#34;&gt;React.createClass&lt;/h3&gt;
&lt;p&gt;React.createClass is the original style for defining React components, and is still the preferred style in the React documentation.&lt;/p&gt;
&lt;p&gt;Here’s what a theoretical SaveButton component looks like in this style.  It is a simple component that listens for clicks and then uses a separate dispatcher object to send a request to save the data on the page.  After saving the button will either show some specified saved text or &amp;ldquo;Saved&amp;rdquo;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; React from ‘react’;
&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; {dispatcher} from ‘.&lt;span style=&#34;color:#ff79c6&#34;&gt;/&lt;/span&gt;lib&lt;span style=&#34;color:#ff79c6&#34;&gt;/&lt;/span&gt;dispatcher’;

&lt;span style=&#34;color:#ff79c6&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; SaveButton &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; React.createClass({

    propTypes&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; {
        &lt;span style=&#34;color:#6272a4&#34;&gt;//text to show after the component is saved
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;        savedText&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; React.PropTypes.string.isRequired,
        &lt;span style=&#34;color:#6272a4&#34;&gt;//primary text to show on the button
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;        text&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; React.PropTypes.string.isRequired,
    },

    getDefaultProps() {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; {
             savedText&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; ‘Saved’,
        };
    },

    getInitialState() {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; { saved&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;false&lt;/span&gt; };
    },

    save() {
        dispatcher.sendMessage(‘saveData’);
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.setState({saved&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;true&lt;/span&gt;});
    },

    render() {
        &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; {text, savedText} &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.props;
        &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; (&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;span className&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;“button” onClick&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;{&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.save}&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;
           {&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.state.saved &lt;span style=&#34;color:#ff79c6&#34;&gt;?&lt;/span&gt; savedText &lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; text}
        &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;/span&amp;gt;);
    },
});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;One of the best things about this style is its cohesive nature.  Everything about the component is described as a single object passed to React.createClass.  Since it is just an object that React processes, it is also able to accommodate more usage styles than ES6 classes and functional components.  Specifically we can use &lt;a href=&#34;https://facebook.github.io/react/docs/reusable-components.html#mixins&#34;&gt;mixins&lt;/a&gt; and add declarative properties like propTypes directly to the component definition.&lt;/p&gt;
&lt;p&gt;The downside of the createClass approach is the custom nature of it.  External tools can’t inspect a component declaration and know what functions and methods will be available on the final component without either some deep inspection of the React source code or pre-existing knowledge of React.createClass that somebody has to document and maintain.&lt;/p&gt;
&lt;h3 id=&#34;es6-classes&#34;&gt;ES6 Classes&lt;/h3&gt;
&lt;p&gt;Last March, with React v0.13, the React team introduced a second syntax for React components using ES6 classes.  The constraints of the ES6 class definition change the component API in a few ways.  With ES6 classes there is no way to add properties to the class property as part of the main definition, they need to be added afterwards &lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;.  Some niceties that are possible with React.createClass don’t work with ES6 classes as well.  Mixins aren’t possible, and React will no longer “autobind” your functions to the component instance, so when passing class methods as callbacks in your components it is necessary to bind it to the current context, either by using arrow functions like
&lt;code&gt;&amp;lt;span onClick= {() =&amp;gt; this.save()} &amp;gt;&lt;/code&gt; or by binding the function like &lt;code&gt;this.save = this.save.bind(this)&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; React from ‘react’;
&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; {dispatcher} from ‘.&lt;span style=&#34;color:#ff79c6&#34;&gt;/&lt;/span&gt;lib&lt;span style=&#34;color:#ff79c6&#34;&gt;/&lt;/span&gt;dispatcher’;

&lt;span style=&#34;color:#ff79c6&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; SaveButton &lt;span style=&#34;color:#ff79c6&#34;&gt;extends&lt;/span&gt; React.Component {

    constructor(props) {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;super&lt;/span&gt;(props);
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.state &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; { saved&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;false&lt;/span&gt; };
    }

    save() {
        dispatcher.sendMessage(‘saveData’);
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.setState({saved&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;true&lt;/span&gt;});
    },

    render() {
        &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; {text, savedText} &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.props;
        &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; (&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;span className&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;button&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;
           {&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.state.saved &lt;span style=&#34;color:#ff79c6&#34;&gt;?&lt;/span&gt; savedText &lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; text}
        &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;/span&amp;gt;);
    },
});

SaveButton.propTypes &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {
    savedText&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; React.PropTypes.string.isRequired,
    text&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; React.PropTypes.string.isRequired,
};

SaveButton.defaultProps &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {
    savedText&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; ‘Saved’,
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;While this approach makes some syntactic compromises and loses mixins, it has the advantage of standardization and tooling support.  A good JavaScript tool can easily tell that a SaveButton should have render and save methods, as well as detecting the methods it inherits from React.Component.  This is useful for things like auto-complete and linting, as well as (theoretically) run-time performance.&lt;/p&gt;
&lt;h3 id=&#34;pure-functional-components&#34;&gt;Pure Functional Components&lt;/h3&gt;
&lt;p&gt;Last fall with React 0.14, React added a 3rd component style.  Functional components dispose of many of the secondary features of React, and focus on the &lt;code&gt;render&lt;/code&gt; function.  They are the least powerful of all the component syntaxes.  In addition to losing mixins, pure functional components don’t have the life-cycle functions of the class based syntaxes and also don’t have any internal state.  For these components, all state must be managed externally through something like Redux, or parent components that do have state.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; React from ‘react’;
&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; {dispatcher} from ‘.&lt;span style=&#34;color:#ff79c6&#34;&gt;/&lt;/span&gt;lib&lt;span style=&#34;color:#ff79c6&#34;&gt;/&lt;/span&gt;dispatcher’;

&lt;span style=&#34;color:#ff79c6&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; SaveButton &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; ({text, savedText, isSaved, setSaved}) =&amp;gt; {
    &lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; save &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; () =&amp;gt;{
        dispatcher.sendMessage(‘saveData’);
        setSaved();
    },
    &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; (&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;span className&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;“button” onClick&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;{save}&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;
       {isSaved &lt;span style=&#34;color:#ff79c6&#34;&gt;?&lt;/span&gt; savedText &lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; text}
    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;/span&amp;gt;);
};

SaveButton.propTypes &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {
    &lt;span style=&#34;color:#6272a4&#34;&gt;//text to show after the component is saved
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    savedText&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; React.PropTypes.string.isRequired,
    &lt;span style=&#34;color:#6272a4&#34;&gt;//primary text to show on the button
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    text&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; React.PropTypes.string.isRequired,
    &lt;span style=&#34;color:#6272a4&#34;&gt;// has the data already been saved?
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    isSaved&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; React.PropTypes.bool.isRequired,
    &lt;span style=&#34;color:#6272a4&#34;&gt;// a function to update the application state and mark the page as saved
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    setSaved&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; React.PropTypes.func.isRequired,
};

SaveButton.defaultProps &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {
    savedText&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; ‘Saved’,
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Despite being the least powerful of the 3 component styles, functional components do have some advantages.  First of all, they’re very simple.  It is easy to see what is going on with them, and easy for React to optimize for them.  Like ES6 classes, they’re easy to understand for 3rd party tools since they’re “just functions”, and easy to explain to new developers for the same reason.  They also work well with systems like Redux which already encourages pulling state out of components into global stores.&lt;/p&gt;
&lt;h2 id=&#34;choosing-a-component-style&#34;&gt;Choosing a component style&lt;/h2&gt;
&lt;p&gt;So given these 3 styles, how do you choose which style to use for a component?  Balance a desire for consistency with a respect for the &lt;a href=&#34;https://en.wikipedia.org/wiki/Rule_of_least_power&#34;&gt;Principle of Least Power&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For consistency purposes, don’t use more than 2 of these styles within a single project.  This mostly breaks down to “don’t use createClass and ES6 classes” together in the same project.  There are significant differences in capability and complexity between the first 2 styles and functional components. But the class based styles are similar enough that using both adds complexity but fails to do much in terms of signaling intent.  Switching between 2 different styles of communicating a concept should also indicate a meaningful difference in intent.&lt;/p&gt;
&lt;p&gt;Of course the most consistent approach would be to always use createClass, since it is the most powerful and any component that can be implemented in the other 2 styles can be implemented using createClass.  This is where the principle of least power comes in.  Here is Tim Berners-Lee&amp;rsquo;s initial description of that principle:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Computer Science in the 1960s to 80s spent a lot of effort making languages which were as powerful as possible. Nowadays we have to appreciate the reasons for picking not the most powerful solution but the least powerful. The reason for this is that the less powerful the language, the more you can do with the data stored in that language. If you write it in a simple declarative from, anyone can write a program to analyze it in many ways. The Semantic Web is an attempt, largely, to map large quantities of existing data onto a common language so that the data can be analyzed in ways never dreamed of by its creators. If, for example, a web page with weather data has RDF describing that data, a user can retrieve it as a table, perhaps average it, plot it, deduce things from it in combination with other information. At the other end of the scale is the weather information portrayed by the cunning Java applet. While this might allow a very cool user interface, it cannot be analyzed at all. The search engine finding the page will have no idea of what the data is or what it is about. This the only way to find out what a Java applet means is to set it running in front of a person.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The less powerful react components styles are the more readable styles, both for humans and computers. That readability also limits the classes of errors and unexpected behaviors we can enact. So we should strive for simple components where we can, while balancing that with our desire for consistency.&lt;/p&gt;
&lt;p&gt;For projects looking into this, there are a few simple questions that you can answer to decide which style to use.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Do you need to integrate with non-React libraries that modify the DOM?&lt;/li&gt;
&lt;li&gt;Do you need to manage state within your components (IE are you not using an external state management library like Redux)?&lt;/li&gt;
&lt;li&gt;Do you need to use mixins for anything in your project?&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If you answered yes to any of these questions, then you need to include a class based component style in your options for your projects.  If you answered yes to #3, then you will need to use React.createClass.&lt;/p&gt;
&lt;p&gt;Once you’ve made those decisions at the project level, the decisions are easy for an individual component.  If you answered no to all of the questions above (unlikely for a large project, but possible), you should always use functional components.  If not, you can ask the same 3 questions for each new component.  If the answer to all of the questions are no for a component, use a functional component, otherwise use the class based style you’ve chosen for your project.&lt;/p&gt;
&lt;h3 id=&#34;more-resources&#34;&gt;More Resources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://facebook.github.io/react/docs/reusable-components.html#es6-classes&#34;&gt;The React documentation&lt;/a&gt; is the best place to look at the benefits and tradeoffs of the different component styles&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://jamesknelson.com/should-i-use-react-createclass-es6-classes-or-stateless-functional-components/&#34;&gt;James Nelson wrote a similar guide last year&lt;/a&gt; focused on the decision tree of what style to use for a component.  He dismisses the createClass style completely and has a similar but slightly different set of questions to ask.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/facebook/react/issues/5677&#34;&gt;This github thread&lt;/a&gt; makes the important distinction that functional components are not yet optimized in any special way, though they may be in the future.&lt;/li&gt;
&lt;/ul&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;Technically you can also use an ES5 class based style, but I’m going to ignore that.  It is not a common idiom for React programs as far as I can tell.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;There is a proposal for adding static properties to ES6 classes, but it is still in early stages right now and is not guaranteed to end up as part of the ECMAScript spec.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>Ack Tips</title>
      <link>https://benmccormick.org/2016/04/30/104825.html</link>
      <pubDate>Sat, 30 Apr 2016 11:48:25 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2016/04/30/104825.html</guid>
      <description>&lt;p&gt;&lt;em&gt;Last summer I briefly considered creating a separate blog focused on command line tools.  The idea is that the articles would be shorter and more practical than the longer pieces I write here.  I ended up scrapping the idea, but had written a few posts on one of my favorite command line tools Ack, so I wanted to preserve them here, as a single, longer piece, separated into 3 &amp;ldquo;tips&amp;rdquo;&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&#34;1-prefer-ack-or-ag-to-grep&#34;&gt;#1: Prefer ack or ag to grep&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;http://linux.die.net/man/1/grep&#34;&gt;grep&lt;/a&gt; is one of the most well known unix utilties.  If you&amp;rsquo;ve had any exposure to the command line at all, you&amp;rsquo;ve probably searched for something using grep.  grep&amp;rsquo;s standalone use is searching for content inside of files, but with Unix&amp;rsquo;s piping philosophy it is useful as a general search and filtering tool.  Originally created for Version 4 Unix 42 years ago, it has been a staple of *Nix operating systems ever since.   If you&amp;rsquo;ve been using it for even half that time, I&amp;rsquo;m sure a blog post isn&amp;rsquo;t enough to convince you to stop.  But for the rest of us, there&amp;rsquo;s an opportunity to do better.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://beyondgrep.com/&#34;&gt;ack&lt;/a&gt; and &lt;a href=&#34;https://github.com/ggreer/the_silver_searcher&#34;&gt;ag&lt;/a&gt; &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; are similar projects with the same goal: providing a better experience than grep when searching directories of files, particularly for programmers.  The key selling points:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Improved speed when searching through directories&lt;/li&gt;
&lt;li&gt;Ignores version control and binary files by default when searching&lt;/li&gt;
&lt;li&gt;Easy filtering by file-type&lt;/li&gt;
&lt;li&gt;A cleaner API for searching directories, without adding complexity to the single file case&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This is easiest to see by comparing commands.&lt;/p&gt;
&lt;h4 id=&#34;searching-for-javascript-in-a-file&#34;&gt;Searching for &amp;ldquo;javascript&amp;rdquo; in a file&lt;/h4&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;grep javascript foo.txt
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;ack javascript foo.txt
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id=&#34;searching-every-file-in-the-current-directory-for-javascript&#34;&gt;Searching every file in the current directory for &amp;ldquo;javascript&amp;rdquo;&lt;/h4&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;grep -r javascript .
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;ack javascript
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id=&#34;searching-every-file-in-the-current-directory-for-javascript-excluding-a-git-directory&#34;&gt;Searching every file in the current directory for &amp;ldquo;javascript&amp;rdquo;, excluding a .git directory&lt;/h4&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;grep -r javascript . $(find . -type f | grep -v &#39;\.git&#39;)
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;ack javascript
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id=&#34;searching-every-html-file-in-the-current-directory-for-javascript-excluding-a-git-directory&#34;&gt;Searching every HTML file in the current directory for &amp;ldquo;javascript&amp;rdquo;, excluding a .git directory&lt;/h4&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;grep -r javascript . $(find . -name &#39;*.html&#39; -or -name &#39;*.htm&#39;| grep -v &#39;\.git&#39;)
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;ack --html javascript
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Basically, as the complexity of what you&amp;rsquo;re trying to do increases in terms of multiple files, the overhead of using grep increases proportionately.  Because ack and ag are optimized for common use cases, they&amp;rsquo;re able to scale much better.&lt;/p&gt;
&lt;h3 id=&#34;2-use-ack-to-get-familiar-with-a-new-codebase&#34;&gt;#2: Use Ack to get familiar with a new codebase&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;http://beyondgrep.com/&#34;&gt;ack&lt;/a&gt; is an incredibly useful tool when approaching a new codebase, especially if you&amp;rsquo;re focused on a specific feature. It allows you to quickly get a view of the codebase, and then zero in on the functionality you&amp;rsquo;re interested in.  To see how this works, let&amp;rsquo;s use jQuery&amp;rsquo;s &lt;a href=&#34;https://github.com/jquery/jquery&#34;&gt;source repo&lt;/a&gt; as an example, and see what happens if we want to get a look at how it implements ajax.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;❯ git clone git@github.com:jquery/jquery.git
❯ &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;cd&lt;/span&gt; jquery
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We can start by trying to get a general idea of the size of the codebase.  Running &lt;code&gt;ack -f&lt;/code&gt; to show all files in the directory will immediately overrun our terminal, so we can get a file count using &lt;code&gt;wc&lt;/code&gt; instead&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;❯ ack -f |wc -l
    &lt;span style=&#34;color:#bd93f9&#34;&gt;249&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Ok thats a good amount of files.  But how many of them are actually source files?  We can filter down to just the javascript files.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;❯ ack -f --js |wc -l
    &lt;span style=&#34;color:#bd93f9&#34;&gt;155&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;But thats probably still a bit high, since not all of the JavaScript files are source files.  A quick &lt;code&gt;ls&lt;/code&gt; shows that we probably want to filter down to the src directory.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;❯ ack -f --js src |wc -l
    &lt;span style=&#34;color:#bd93f9&#34;&gt;92&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Ok so now we&amp;rsquo;re down to 92 source files.  Still a bit much, but its probably worth printing them with &lt;code&gt;ack -f --js src&lt;/code&gt; at this point to get an idea of the directory structure.  When we do that, we can see there&amp;rsquo;s an ajax folder, which is probably what we&amp;rsquo;re interested in.  To make sure we&amp;rsquo;re not missing related files, we can continue on to searching for files with ajax in the file name directly.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;❯ ack -g --js ajax src
    src/ajax/jsonp.js
    src/ajax/load.js
    src/ajax/parseJSON.js
    src/ajax/parseXML.js
    src/ajax/script.js
    src/ajax/var/location.js
    src/ajax/var/nonce.js
    src/ajax/var/rquery.js
    src/ajax/xhr.js
    src/ajax.js
    src/event/ajax.js
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That gets us down to 11 files to look at.  But we might be getting a bit greedy.  Not every file related to ajax may have ajax in the file path.  We can use the &lt;code&gt;-l&lt;/code&gt; option of ack to display the list of files that contain ajax somewhere in their text.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;❯ ack --js -l ajax src
    src/ajax/jsonp.js
    src/ajax/load.js
    src/ajax/script.js
    src/ajax/xhr.js
    src/ajax.js
    src/event/ajax.js
    src/jquery.js
    src/manipulation/_evalUrl.js
    src/serialize.js
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Ok that adds 3 additional files with ajax references.  But its not clear that they&amp;rsquo;re relevant to jQuery&amp;rsquo;s ajax implementation, it may just be a file reference or comment.  Lets use ack to get a quick look at how ajax is referenced in those files.  This part gets a bit more complicated.  We can use ack&amp;rsquo;s &lt;code&gt;-v&lt;/code&gt; option to invert our matching and find non-matching inputs, then use unix piping to filter our previous command.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;❯ ack --js -l ajax src |ack -v ajax
    src/jquery.js
    src/manipulation/_evalUrl.js
    src/serialize.js
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now we can use ack&amp;rsquo;s &lt;code&gt;-x&lt;/code&gt; argument to search the files piped in through standard input.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;❯ ack --js -l ajax src |ack -v ajax|ack -x ajax

    src/jquery.js
    20:     &amp;quot;./ajax&amp;quot;,
    21:     &amp;quot;./ajax/xhr&amp;quot;,
    22:     &amp;quot;./ajax/script&amp;quot;,
    23:     &amp;quot;./ajax/jsonp&amp;quot;,
    24:     &amp;quot;./ajax/load&amp;quot;,
    25:     &amp;quot;./event/ajax&amp;quot;,

    src/manipulation/_evalUrl.js
    2:      &amp;quot;../ajax&amp;quot;
    6:      return jQuery.ajax({
    9:              // Make this explicit, since user can override this through ajaxSetup (#11264)

    src/serialize.js
    61:             traditional = jQuery.ajaxSettings &amp;amp;&amp;amp; jQuery.ajaxSettings.traditional;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;So we can see pretty quickly that these files are safe to ignore in terms of understanding how ajax works in jQuery.  They&amp;rsquo;re just module loads, an actual call to the ajax method for other purposes, and settings serialization. It is useful to note that &lt;code&gt;src/ajax&lt;/code&gt; is loaded into the main jQuery file first. Its probably worth looking at it as the starting point for our investigation. We&amp;rsquo;re well on our way to diving into the ajax functionality, able to focus on 11 of the 249 files in the repo immediately, already knowing how those files are loaded into the main library.&lt;/p&gt;
&lt;p&gt;This was just a simple example.  Whenever you&amp;rsquo;re spelunking into new code territory, consider using ack to get your bearings.  Things go a lot faster when you know the lay of the land in advance.&lt;/p&gt;
&lt;h3 id=&#34;3-take-advantage-of-acks-configurability&#34;&gt;#3: Take advantage of Ack&amp;rsquo;s configurability&lt;/h3&gt;
&lt;p&gt;One of the nice things about &lt;a href=&#34;http://beyondgrep.com/&#34;&gt;ack&lt;/a&gt; is the fact that it takes an &lt;code&gt;.ackrc&lt;/code&gt; configuration file &lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;. These files can be scoped at a directory level, a user level or at a root level, and mirror the options available on the executable itself.  This allows you to extend and customize acks behavior in 3 primary ways.&lt;/p&gt;
&lt;h4 id=&#34;a-add-new-filetypes-and-bundle-existing-ones&#34;&gt;a. Add new filetypes, and bundle existing ones&lt;/h4&gt;
&lt;p&gt;One of ack&amp;rsquo;s most useful features is the ability to add a &lt;code&gt;--&amp;lt;filetype&amp;gt;&lt;/code&gt; flag to your searches to restrict your searches to a specific filetype.   ack comes with 75 builtin types including almost all common languages.  But those aren&amp;rsquo;t always good enough.  To handle obscure languages, and not so obscure syntaxes like handlebars templates, ack lets you define new filetypes.  You&amp;rsquo;re also able to modify existing filetypes to add additional file extensions to include under that filetype.  So for instance my ackrc includes these lines:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;--type-add
hbs=hbs
--type-add
js=js,es6
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The first 2 lines allow me to specifically search handlebars files, which are where all of the html content for my work projects is stored.  The next 2 lines include es6 files in my JavaScript searches, useful since I append JavaScript files that I intend to process with &lt;a href=&#34;https://babeljs.io/&#34;&gt;Babel&lt;/a&gt; with the &lt;code&gt;.es6&lt;/code&gt; extenstion.  Customizing the js extension allows me to search all of my JavaScript together.  You can also define richer types in ackrc &lt;a href=&#34;http://beyondgrep.com/documentation/ack-2.14-man.html#defining_your_own_types&#34;&gt;based on file names using regular expressions or direct name matching&lt;/a&gt;.&lt;/p&gt;
&lt;h4 id=&#34;b-set-default-options&#34;&gt;b. Set default options&lt;/h4&gt;
&lt;p&gt;Any option that the ack executable takes can have a default set or changed in an ackrc file.  This is mainly useful for the display option.  By default ack groups matches from different files and gives the file information above each group of matches.  It also shows all output in color.  Any of those things can be disabled or changed in your ackrc file.&lt;/p&gt;
&lt;h4 id=&#34;c-exclude-unwanted-directories-or-files&#34;&gt;c. Exclude unwanted directories or files&lt;/h4&gt;
&lt;p&gt;Oftentimes there are a predictable group of files that you may want to ignore in searches.  Perhaps you have a build directory that mirrors your source code, or documentation files mingled with your source.  You can put &lt;code&gt;--ignore-directory&lt;/code&gt; or &lt;code&gt;--ignore-file&lt;/code&gt;.  Ignore directory takes a directory name, while ignore-file takes matches in the same format as the custom filetypes mentioned above.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re starting to use ack, don&amp;rsquo;t miss the chance to make your searches even more efficient by removing any rough edges with an &lt;code&gt;.ackrc&lt;/code&gt;.&lt;/p&gt;
&lt;h4 id=&#34;installation-instructions&#34;&gt;Installation Instructions&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://beyondgrep.com/install/&#34;&gt;ack&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/ggreer/the_silver_searcher#installing&#34;&gt;ag&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;footnotes&#34;&gt;
&lt;ol&gt;
    &lt;li class=&#34;footnote&#34; id=&#34;fn:1&#34;&gt;
    &lt;p&gt;
       ack came first; ag was created as a faster version of ack.  ack is written in perl, making it more portable, and has a few more configuration options.  ag is written in C and is generally faster.  Your choice may vary depending on your use case.
    &lt;/p&gt;
    &lt;a href=&#34;#fnref:1&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;
    &lt;/li&gt;
    &lt;li class=&#34;footnote&#34; id=&#34;fn:2&#34;&gt;
        &lt;p&gt;
       This is also one of the main traits that separates ack from &lt;a href=&#34;https://github.com/ggreer/the_silver_searcher&#34;&gt;ag&lt;/a&gt;.
        &lt;/p&gt;
        &lt;a href=&#34;#fnref:2&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Stability vs Decline</title>
      <link>https://benmccormick.org/2016/03/09/010439.html</link>
      <pubDate>Wed, 09 Mar 2016 02:04:39 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2016/03/09/010439.html</guid>
      <description>&lt;p&gt;My post on &lt;a href=&#34;http://benmccormick.org/2016/03/07/the-sad-state-of-the-backbone-ecosystem/&#34;&gt;the sad state of the Backbone ecosystem&lt;/a&gt; from this weekend was surprisingly popular.  I got a lot of responses pointing out &lt;a href=&#34;https://twitter.com/_benmccormick/status/707063566940016645&#34;&gt;some things I got wrong&lt;/a&gt;, sharing my concerns, or pushing back on my main points.  Objections to the post came in 2 primary forms, which I want to quickly address.  The first concern is that the Backbone ecosystem doesn&amp;rsquo;t matter. The second concern is that the trend I&amp;rsquo;m identifying as decline and decay is actually stability.&lt;/p&gt;
&lt;h3 id=&#34;does-backbones-ecosystem-matter&#34;&gt;Does Backbone&amp;rsquo;s ecosystem matter?&lt;/h3&gt;
&lt;p&gt;The first concern came in 2 main forms.  The first (and more polite) form was from commenters who shared their experience and said that they&amp;rsquo;d found Backbone&amp;rsquo;s core to be enough when combined with their own code.  The second group was a generalization of that, effectively saying that Backbone is a minimal framework, and &lt;strong&gt;real programmers&lt;/strong&gt; can write their own code on top of that.  I&amp;rsquo;m sympathetic to the first framing, much less so to the second.&lt;/p&gt;
&lt;p&gt;One of the beauties of Backbone is that it can be used in a variety of ways.  Its small and simple enough that you can pull it in and use only part of it (maybe just the models or event system for instance), but it has been scaled to be used for large web applications like Trello, Rdio, Backbone, Bitbucket and others. Some of those use cases quite frankly, don&amp;rsquo;t need anything else most of the time.  If you&amp;rsquo;re writing a very simple single screen piece of interactive behavior with Backbone, you don&amp;rsquo;t need any special extra libraries for that.&lt;/p&gt;
&lt;p&gt;I personally work on a large scale web application (~200 Backbone Views) that has been developed for over 3 years and will continue to be developed (hopefully) for a long time. In that situation, having well documented, tested and supported third party libraries for common tasks like rich tables, form validation, UI component libraries, and integrations with other tools is tremendously useful.  As an experienced developer, I&amp;rsquo;m capable of writing all of these things myself, but doing so takes time, and the result is likely to be less stable, less well documented, and less well thought through than a popular open source solution.  To be clear, nobody is obligated to write these things for me.  I&amp;rsquo;m merely making a factual statement that the experience of writing a large web application in Backbone becomes more difficult as the community around the library shrinks.&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s a second reason why down playing the importance of an ecosystem is harmful though.  I&amp;rsquo;ve said that I am capable of writing the various components of an ecosystem myself.  But that&amp;rsquo;s only true of me because I have years of experience writing code, and specifically of working with different libraries that gave me ideas on how those problems should be tackled.  A community that says you should be able to do everything yourself without starting places and good examples is a community that is hostile to beginners.  Let&amp;rsquo;s not let the JavaScript community be that.&lt;/p&gt;
&lt;h3 id=&#34;is-backbone-just-stable&#34;&gt;Is Backbone just stable?&lt;/h3&gt;
&lt;p&gt;The second disagreement (and the most common theme on &lt;a href=&#34;https://news.ycombinator.com/item?id=11237283&#34;&gt;Hacker News&lt;/a&gt;) was that the current state of Backbone and its ecosystem is not sad at all.  Backbone is stable, and thats something to be celebrated.  In some cases this echoed what I actually said in the post.  I specifically called out the core Backbone library as a good example of stable software:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I&amp;rsquo;m starting with Backbone itself to give an idea what a stable mature project graph looks like. Backbone isn&amp;rsquo;t getting the activity it used to, but there&amp;rsquo;s still a steady flow of bug fixes and documentation updates, and issues are being worked through.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Backbone is stable, and in a vacuum that is something to be happy about.  Stability has not prevented it from having an active team of contributors who are continuing to refine it and make small improvements.  This is great, and on it&amp;rsquo;s own would make me incredibly pleased as a user.  The problem comes with the libraries around it.  Excepting Marionette, which appears to be getting ready to launch their long awaited version 3, activity in the ecosystem has stagnated in a different way than Backbone core.&lt;/p&gt;
&lt;p&gt;Unlike Backbone core, secondary libraries have important issues requested by several people being ignored.  I&amp;rsquo;ve chosen to avoid calling out specific projects because I don&amp;rsquo;t think anyone has a responsibility to fix other people&amp;rsquo;s open source problems and don&amp;rsquo;t want to add to open source guilt.  But it is not hard to find examples of this if you browse through popular Backbone packages on Github.&lt;/p&gt;
&lt;p&gt;Unlike Backbone core, secondary libraries sometimes have no clear active maintainer who can be counted on to put out a release in the case of an emergency change being needed.  This matters because Backbone and JavaScript libraries in general live on an unstable platform.  Browsers change all the time.  While they do their best to maintain backwards compatibility, browsers occasionally introduce bugs, and occasionally fix bugs that a library may have been relying on or working around. In addition to disaster scenarios like that, tools change and best practices change over time.  When documentation stagnates and doesn&amp;rsquo;t keep up with changes, libraries become less useful and approachable over time.  Most Backbone tutorials on the web, and the documentation for many libraries, assume that scripts will be loaded in directly and that variables will be referenced through namespacing.  In a world where module loaders are becoming a default tool for larger JavaScript applications, thats a gap that makes libraries hard to learn, or teaches out of date practices to less experienced developers.&lt;/p&gt;
&lt;p&gt;A healthy stable project ought to be able to check off 3 boxes.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;It meets the goals of its authors&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Major bugs are fixed as they&amp;rsquo;re reported.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;It is maintained to the extent that as new issues come in, they are responded to and dealt with&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;That definition could mean that a library handles a single use cases, and there is rare activity because nobody ever encounters any problems.  But for larger projects, this likely means refinements to fix small issues, documentation changes, and an occasional big bugfix over time. Its these things that make the difference between stable software and abandonware.&lt;/p&gt;
&lt;h3 id=&#34;what-does-it-matter-in-the-end&#34;&gt;What does it matter in the end?&lt;/h3&gt;
&lt;p&gt;I didn&amp;rsquo;t write my original post to say that Backbone is dead.  I wanted to highlight a way in which the experience of using it has declined over time.  It is specifically a way that makes using Backbone harder for me.  I&amp;rsquo;m grateful to the many people who have built Backbone and the ecosystem around it, and think it is still a very useful tool.  This ecosystem issue does make me unlikely to recommend Backbone for folks who are building web applications &amp;ldquo;at scale&amp;rdquo;.  I think Ember or possibly React are better choices for that.  For small one off projects, and for content focused sites that need as little JavaScript as possible while still providing a rich experience, Backbone is a great choice.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>The Sad State of the Backbone Ecosystem</title>
      <link>https://benmccormick.org/2016/03/07/000640.html</link>
      <pubDate>Mon, 07 Mar 2016 01:06:40 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2016/03/07/000640.html</guid>
      <description>&lt;p&gt;For the past 2 years, ~90% of my coding time has been spent working on a large scale Backbone.js app.  In February 2014, the Backbone community was in a fairly good place.  The core library had reached 1.0 the previous year and had a strong team around it.  Marionette had emerged as a de-facto standard for web applications &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.  There were Backbone specific plugins for many tasks, and generally gaps could be filled using the jQuery plugin ecosystem, or a framework agnostic library.  At the time, Backbone would have been a very defensible choice as a library for starting a new web development, as a simpler and more stable alternative to AngularJS, the current &amp;ldquo;hot&amp;rdquo; framework.&lt;/p&gt;
&lt;p&gt;Since then a few things have happened.  First, React has taken off, while Angular and Ember have continued to grow and learn from React and each other. Angular and React have benefited from significant marketing and financial support for a core development team that have helped them grow quickly.  Google Trends gives a pretty good idea of how that has turned out.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;Google_Trends_-_Web_Search_interest__angular_js__react_js__backbone_js__ember_js_-_Worldwide__Jan_2010_-_Feb_2016.png&#34; alt=&#34;Google trends graph&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; &lt;em&gt;I&amp;rsquo;ve changed the above graph from an original that used angular.js, backbone.js, ember.js, and react.js as the search terms.  Only Backbone prefixes itself with a .js that way, and it undersold the other libraries, especially Angular.  I believe that this chart more accurately reflects usage trends.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Secondly, Backbone&amp;rsquo;s author, &lt;a href=&#34;https://twitter.com/jashkenas&#34;&gt;Jeremy Ashkenas&lt;/a&gt; made a decision to call Backbone &amp;ldquo;finished&amp;rdquo; in terms of API and feature set after the 1.0 release.  This has the advantage of leaving Backbone as by far the most stable major JavaScript framework, but hinders efforts to pull in lessons from other frameworks &lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;Finally, whether as a result of the first 2 items or due to some other factor, the ecosystem around Backbone has crumbled.  While Backbone&amp;rsquo;s core has stabilized, it still has a team of maintainers who are actively managing the project.  That does not appear to be the case for many of the other libraries in the Backbone ecosystem.  To investigate my perception of this, I decided to look at the contribution graphs of popular Backbone libraries to see the trends over the last 2 years.  I built a list of libraries based on the projects that the bower registry returns for the backbone keyword, looking for projects with at least 400 github stars&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;. That lead to a list of 24 projects below.&lt;/p&gt;
&lt;p&gt;To be clear, I&amp;rsquo;m not posting this as a criticism of anyone.  Open source is a volunteer effort, and maintaining a project is hard and often doesn&amp;rsquo;t make sense when the author has moved on to other challenges.  This is simply an honest look at where the Backbone ecosystem stands, with the goal of helping those of us who are building Backbone applications or considering using it to evaluate the ecosystem honestly.&lt;/p&gt;
&lt;h3 id=&#34;1-backbone&#34;&gt;1. Backbone&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;Contributors_to_jashkenas_backbone.png&#34; alt=&#34;backbone graph&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Open issues:&lt;/strong&gt; 54&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Issues closed in 2016:&lt;/strong&gt; 50+&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Last Release&lt;/strong&gt;: 3 days ago (March 3rd 2016)&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m starting with Backbone itself to give an idea what a stable mature project graph looks like.  Backbone isn&amp;rsquo;t getting the activity it used to, but there&amp;rsquo;s still a steady flow of bug fixes and documentation updates, and issues are being worked through.&lt;/p&gt;
&lt;h3 id=&#34;2-marionette&#34;&gt;2. Marionette&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;Contributors_to_marionettejs_backbone_marionette.png&#34; alt=&#34;mn graph&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Open Issues:&lt;/strong&gt; 107&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Issues closed in 2016:&lt;/strong&gt; 30+&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Last Release&lt;/strong&gt;: November 22 2015&lt;/p&gt;
&lt;p&gt;Of all the graphs here, this one is the nearest and dearest to me.  I&amp;rsquo;ve contributed code to Marionette, and have written about it &lt;a href=&#34;http://benmccormick.org/marionette-explained/&#34;&gt;many times&lt;/a&gt; on this blog.  Marionette still is seeing plenty of work, but as the contributors have cycled through, work on a long awaited version 3 with important improvements has sat on a branch for over a year.  This is a great library, but it hasn&amp;rsquo;t been immune to the wider issues in the ecosystem.&lt;/p&gt;
&lt;h3 id=&#34;3-backbonerelational&#34;&gt;3. Backbone.Relational&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;Contributors_to_PaulUithol_Backbone-relational.png&#34; alt=&#34;bb-relational&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Open Issues:&lt;/strong&gt; 122&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Issues closed in 2016:&lt;/strong&gt; 0&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Last Release:&lt;/strong&gt; August 19 2015&lt;/p&gt;
&lt;p&gt;Backbone.Relational is another &amp;ldquo;stable&amp;rdquo; library.  On its own, there&amp;rsquo;s nothing wrong with that, this is a focused library that doesn&amp;rsquo;t necessarily need a lot of new features.  But this is the start of a pattern.&lt;/p&gt;
&lt;h3 id=&#34;4-backbone-forms&#34;&gt;4. backbone-forms&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;Contributors_to_powmedia_backbone-forms.png&#34; alt=&#34;bb-forms&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Open Issues:&lt;/strong&gt; 172&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Issues closed in 2016:&lt;/strong&gt; 14&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Last Release:&lt;/strong&gt; Jan 21, 2016&lt;/p&gt;
&lt;h3 id=&#34;5-backgrid&#34;&gt;5. backgrid&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;Contributors_to_wyuenho_backgrid.png&#34; alt=&#34;backgrid&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Open Issues:&lt;/strong&gt; 111&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Issues closed in 2016:&lt;/strong&gt; 3&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Last Release:&lt;/strong&gt; Jan 21 2014&lt;/p&gt;
&lt;p&gt;This is the first project on this list that I wouldn&amp;rsquo;t consider to be actively maintained.  Commits over the past 2 years have been primarily about keeping tooling and documentation up to date.&lt;/p&gt;
&lt;h3 id=&#34;6-backbonelocalstorage&#34;&gt;6. backbone.localStorage&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;Contributors_to_jeromegn_Backbone_localStorage.png&#34; alt=&#34;localstorage&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Open Issues:&lt;/strong&gt; 45&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Issues closed in 2016:&lt;/strong&gt; 1&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Last Release:&lt;/strong&gt; Jan 22 2015&lt;/p&gt;
&lt;h3 id=&#34;7-backbonestickit&#34;&gt;7. backbone.stickit&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;Contributors_to_NYTimes_backbone_stickit.png&#34; alt=&#34;stickit&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Open Issues:&lt;/strong&gt; 26&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Issues closed in 2016:&lt;/strong&gt; 1&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Last Release:&lt;/strong&gt; May 11 2015&lt;/p&gt;
&lt;h3 id=&#34;8-backbonepaginator&#34;&gt;8. backbone.paginator&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;Contributors_to_backbone-paginator_backbone_paginator.png&#34; alt=&#34;paginator&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Open Issues:&lt;/strong&gt; 20&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Issues closed in 2016:&lt;/strong&gt; 7+&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Last Release:&lt;/strong&gt; Feb 3 2016&lt;/p&gt;
&lt;h3 id=&#34;9-backbone-validation&#34;&gt;9. Backbone-validation&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;Contributors_to_thedersen_backbone_validation.png&#34; alt=&#34;validation&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Open Issues:&lt;/strong&gt; 79&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Issues closed in 2016:&lt;/strong&gt; 1&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Last Release:&lt;/strong&gt; May 8 2015&lt;/p&gt;
&lt;p&gt;I have personal experience with the abandoned state of this library since my team has been working off a forked version of it for 6 months while waiting on maintainers to address a &lt;a href=&#34;https://github.com/thedersen/backbone.validation/pull/302&#34;&gt;pull request&lt;/a&gt;.  Like many others here, it appears to be a project that the core team moved on from and nobody else had the motivation or time to pick it up.  While there&amp;rsquo;s nothing wrong with that, it makes it hard to rely on these projects.&lt;/p&gt;
&lt;h3 id=&#34;10-knockback&#34;&gt;10. Knockback&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;Contributors_to_kmalakoff_knockback.png&#34; alt=&#34;knockback graph&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Open Issues:&lt;/strong&gt; 4&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Issues closed in 2016:&lt;/strong&gt; 1&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Last Release:&lt;/strong&gt; Sep 28 2015&lt;/p&gt;
&lt;h3 id=&#34;11-exoskeleton&#34;&gt;11. Exoskeleton&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;Contributors_to_paulmillr_exoskeleton.png&#34; alt=&#34;exoskeleton graph&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Open Issues:&lt;/strong&gt; 21&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Issues closed in 2016:&lt;/strong&gt; 2&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Last Release:&lt;/strong&gt; August 4 2014&lt;/p&gt;
&lt;h3 id=&#34;12-backbonedualstorage&#34;&gt;12. Backbone.dualstorage&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;Banners_and_Alerts_and_Contributors_to_nilbus_Backbone_dualStorage.png&#34; alt=&#34;backbone.dualstorage&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Open Issues:&lt;/strong&gt; 30&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Issues closed in 2016:&lt;/strong&gt; 0&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Last Release:&lt;/strong&gt; Feb 16 2015&lt;/p&gt;
&lt;h3 id=&#34;13-backbone-react-component&#34;&gt;13. Backbone-react-component&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;Contributors_to_magalhas_backbone-react-component.png&#34; alt=&#34;backbone react component&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Open Issues:&lt;/strong&gt; 8&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Issues closed in 2016:&lt;/strong&gt; 1&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Last Release:&lt;/strong&gt; Nov 6 2015&lt;/p&gt;
&lt;h3 id=&#34;14-backbone-offline&#34;&gt;14. Backbone-offline&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;Contributors_to_alekseykulikov_backbone-offline.png&#34; alt=&#34;backbone-offline&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Open Issues:&lt;/strong&gt; 30&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Issues closed in 2016:&lt;/strong&gt; 0&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Last Release:&lt;/strong&gt; Aug 21 2013&lt;/p&gt;
&lt;p&gt;This project is actually documented as being deprecated and discontinued.  There is talk in the README about building a successor library, but it appears to have never emerged.&lt;/p&gt;
&lt;h3 id=&#34;15-reactbackbone&#34;&gt;15. React.Backbone&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;Contributors_to_clayallsopp_react_backbone.png&#34; alt=&#34;react.backbone&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Open Issues:&lt;/strong&gt; 11&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Issues closed in 2016:&lt;/strong&gt; 0&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Last Release:&lt;/strong&gt; Jan 5 2015&lt;/p&gt;
&lt;p&gt;Interesting, and not encouraging, that the 2 newest libraries at this popularity level are both for helping Backbone users migrate to React, and neither appear to be very active.&lt;/p&gt;
&lt;h3 id=&#34;16-backboneexpoxy&#34;&gt;16. Backbone.expoxy&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;Contributors_to_gmac_backbone_epoxy.png&#34; alt=&#34;backbone.epoxy&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Open Issues:&lt;/strong&gt; 19&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Issues closed in 2016:&lt;/strong&gt; 1&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Last Release:&lt;/strong&gt; Nov 20 2014&lt;/p&gt;
&lt;h3 id=&#34;17-backboneiobind&#34;&gt;17. backbone.iobind&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;Contributors_to_noveogroup_backbone_iobind.png&#34; alt=&#34;backbone.iobind&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Open Issues:&lt;/strong&gt; 16&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Issues closed in 2016:&lt;/strong&gt; 1&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Last Release:&lt;/strong&gt; Dec 10 2014&lt;/p&gt;
&lt;h3 id=&#34;18-backbone-associations&#34;&gt;18. backbone-associations&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;Contributors_to_dhruvaray_backbone-associations.png&#34; alt=&#34;backbone-associations graph&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Open Issues:&lt;/strong&gt; 16&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Issues closed in 2016:&lt;/strong&gt; 0&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Last Release:&lt;/strong&gt; Jun 28 2014&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;re really starting to get into the meat of the dead projects now.  While there are always going to be older projects that were once popular and got a lot of stars and are now abandoned, that shouldn&amp;rsquo;t be this many of the top 20 projects&lt;/p&gt;
&lt;h3 id=&#34;19-backbone-tastypie&#34;&gt;19. backbone-tastypie&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;Contributors_to_PaulUithol_backbone-tastypie.png&#34; alt=&#34;tastypie graph&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Open Issues:&lt;/strong&gt; 12&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Issues closed in 2016:&lt;/strong&gt; 0&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Last Release:&lt;/strong&gt; Oct 26 2013&lt;/p&gt;
&lt;p&gt;This is a single use case library that presumably was abandoned after solving a problem, but its worth including to illustrate that the 400 star bar isn&amp;rsquo;t that hard to hit. A similar search for React projects on bower yields 46 projects with 400+ stars, and React is only ~3 years old.&lt;/p&gt;
&lt;h3 id=&#34;20-backbonesyphon&#34;&gt;20. backbone.syphon&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;Contributors_to_marionettejs_backbone_syphon.png&#34; alt=&#34;syphon graph&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Open Issues:&lt;/strong&gt; 19&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Issues closed in 2016:&lt;/strong&gt; 1&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Last Release:&lt;/strong&gt; Oct 18 2015&lt;/p&gt;
&lt;h3 id=&#34;21-backbone-nested&#34;&gt;21. backbone-nested&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;Contributors_to_afeld_backbone-nested.png&#34; alt=&#34;backbone-nested&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Open Issues:&lt;/strong&gt; 45&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Issues closed in 2016:&lt;/strong&gt; 1&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Last Release:&lt;/strong&gt; Jul 27 2015&lt;/p&gt;
&lt;h3 id=&#34;22-backboneradio&#34;&gt;22. backbone.radio&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;Contributors_to_marionettejs_backbone_radio.png&#34; alt=&#34;backbone.radio&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Open Issues:&lt;/strong&gt; 9&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Issues closed in 2016:&lt;/strong&gt; 0&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Last Release:&lt;/strong&gt; Sep 5 2015&lt;/p&gt;
&lt;p&gt;Backbone.Radio (along with Backbone.syphon) is part of the marionette project.  You can see that those projects at least have continued work during the past year, albeit at a significantly less active rate than during 2014&lt;/p&gt;
&lt;h3 id=&#34;23-backbone-fetch-cache&#34;&gt;23. backbone-fetch-cache&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;Contributors_to_madglory_backbone-fetch-cache.png&#34; alt=&#34;backbone-fetch-cache graph&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Open Issues:&lt;/strong&gt; 26&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Issues closed in 2016:&lt;/strong&gt; 2&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Last Release:&lt;/strong&gt; Feb 16 2014&lt;/p&gt;
&lt;h3 id=&#34;24-backbone-query-parameters&#34;&gt;24. backbone-query-parameters&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;Contributors_to_jhudson8_backbone-query-parameters.png&#34; alt=&#34;backbone-query-parameters&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Open Issues:&lt;/strong&gt; 10&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Issues closed in 2016:&lt;/strong&gt; 0&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Last Release:&lt;/strong&gt; Sep 23 2014&lt;/p&gt;
&lt;p&gt;So what does this look like in aggregate.  Of the &amp;ldquo;top 24&amp;rdquo; Backbone projects, only 2 were started after January 2014, and one of those is a tool to migrate Backbone projects to React, the other was a rebrand of an existing tool.  18 of the top 24 libraries have not had a release in the last 6 months, 9 have not had a release since December 2014 or earlier.  If we classify these libraries as &amp;ldquo;Actively Growing&amp;rdquo;, &amp;ldquo;Actively being developed&amp;rdquo;, &amp;ldquo;Stable and maintained&amp;rdquo;, &amp;ldquo;Flickering Signs of life&amp;rdquo;, &amp;ldquo;All but dead&amp;rdquo;&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;, and &amp;ldquo;Dead&amp;rdquo;, I would personally split that out like this:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;Title&lt;/th&gt;&lt;th&gt;Libraries&lt;/th&gt;&lt;tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Actively Growing&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Actively Developed&lt;/td&gt;&lt;td&gt; Marionette&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Stable + minimally maintained&lt;/td&gt;&lt;td&gt; Backbone, Backbone.Relational, backbone-forms, backbone.paginator, Backbone.syphon, Backbone.radio&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Flickering Signs of life&lt;/td&gt;&lt;td&gt; back grid, knockback,&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;All but Dead&lt;/td&gt;&lt;td&gt; backbone.localstorage, backbone.stickit, backbone-validation, exoskeleton, backbone.dualstorage, backbone.react-component, react.backbone, backbone-nested, backbone-fetch-cache, backbone-query-parameters&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Dead&lt;/td&gt;&lt;td&gt; backbone.offline, backbone.iobind,  backbone.epoxy, backbone-associations, backbone-tastypie&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;It is not a pretty picture right now.  If you&amp;rsquo;re part of the Backbone community, I&amp;rsquo;d love to hear from you on this.  Should we be calling Backbone dead and looking to migrate ASAP?  Do you think I&amp;rsquo;m overselling this problem?  Are there libraries that I&amp;rsquo;m not considering right now that are thriving?  Or is focusing on Backbone-specific libraries a mistake because most developers are pasting together multiple libraries that aren&amp;rsquo;t necessarily tightly tied.&lt;/p&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;When I attended BackboneConf later that year, about 75% of attendees raised their hands when asked if they had used Marionette&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;Some ideas, like a better router or better templating systems, can be pulled in as 3rd party libraries just fine.  But conceptual changes like 1 way data flow or easily composable components from React and the ES6 class model can&amp;rsquo;t easily be pulled into Backbone without changes to the core library.  It&amp;rsquo;s debatable whether those ideas are useful for Backbone, but it is clear that they will not fit within the current state of the library.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;I used Bower rather than npm because it returns search results sorted by stars rather than trying to directly match the query.&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;I don&amp;rsquo;t like calling somebody else&amp;rsquo;s project dead if its not labeled that way and has had recent issues activity&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>Staying Productive</title>
      <link>https://benmccormick.org/2016/01/24/234146.html</link>
      <pubDate>Mon, 25 Jan 2016 00:41:46 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2016/01/25/234146.html</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve been thinking a lot lately about what makes me productive vs unproductive.  A lot of the time Software Developers tend to focus on their tools and environments when they think about productivity.  I&amp;rsquo;m certainly all into that, as you can see if you look &lt;a href=&#34;http://benmccormick.org/learning-vim-in-2014/&#34;&gt;back&lt;/a&gt;, &lt;a href=&#34;http://benmccormick.org/2015/11/25/productive-javascript-development/&#34;&gt;through&lt;/a&gt;, &lt;a href=&#34;http://benmccormick.org/2016/01/11/the-most-interesting-atom-packages-ive-found-so-far/&#34;&gt;my blog&lt;/a&gt;.  But in my mind the most important factors in building productivity are non-software related.&lt;/p&gt;
&lt;h3 id=&#34;setting-goals&#34;&gt;Setting Goals&lt;/h3&gt;
&lt;p&gt;By far the most important thing I&amp;rsquo;ve found for being productive was setting clear goals for what I want to get done.  Without goal posts to aim for, it&amp;rsquo;s hard to tell what you&amp;rsquo;ve really accomplished, and easy to get pulled off onto suboptimal tasks.  Goals are best set with a wider context in mind.  The act of setting and measuring goals tends to make us focus on those areas, so make sure your goals reflect your priorities.  If you set all of your goals around work, it can be easier to justify neglecting your family.  If you set a goal of writing every day, that might overwhelm time for exercising and keeping yourself healthy.  Therefore its helpful to set goals in a holistic way that allows you to judge what you value in the big picture.&lt;/p&gt;
&lt;h3 id=&#34;mechanical--creative-tasks&#34;&gt;Mechanical / Creative Tasks&lt;/h3&gt;
&lt;p&gt;I saw a great &lt;a href=&#34;https://news.ycombinator.com/item?id=10959022&#34;&gt;comment&lt;/a&gt; on Hacker News the other day that differentiated between projects and chores. The idea is that when you&amp;rsquo;re feeling productive you should work on projects, when you&amp;rsquo;re not you should do chores.  One of the biggest boosts to my productivity I&amp;rsquo;ve found was when I started categorizing work in my head as &amp;ldquo;mechanical&amp;rdquo; vs &amp;ldquo;creative&amp;rdquo; tasks.  Mechanical tasks (ie chores) are things that require little mental energy.  They&amp;rsquo;re well defined and possibly onerous.  Examples include filing email, documenting code, code reviews, and low-thinking code tasks like reproducing a client issue or adding a small well-defined feature.  Creative tasks for me tend to look like more involved code changes designing new features, or debugging client issues that aren&amp;rsquo;t obvious.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m not universally energetic or productive.  Some days I can focus intently on a problem, other days I have the attention span of &lt;a href=&#34;https://www.youtube.com/watch?v=SSUXXzN26zg&#34;&gt;the dogs from UP!&lt;/a&gt;.  When I&amp;rsquo;m able to focus, I intentionally put aside mechanical tasks, and leave them for times when I have less energy, continuous time or attention.  Oftentimes I&amp;rsquo;ll even put off higher priority mechanical tasks (or vice versa) to match my mental level to the task, because I end up getting more done sooner in the long run.&lt;/p&gt;
&lt;h3 id=&#34;productive-environments-are-a-thing&#34;&gt;Productive Environments are a thing&lt;/h3&gt;
&lt;p&gt;It&amp;rsquo;s easy to think of productivity as a purely internal thing.  But the environment you&amp;rsquo;re in matters too.  For creative software work that means getting large blocks of non-distracting time.  That requires some intentionality.  I&amp;rsquo;ve been blessed with a workplace where I&amp;rsquo;m given plenty of flexibility.  That means that at times of high distraction-level (big projects, lots of meetings) I tend to actually do most of my work outside of the office, sometimes at weird times.  I use my time at the office for mechanical tasks and meetings, and do the creative work elsewhere.  That&amp;rsquo;s obviously suboptimal, and when I can I try to clear time during days to do creative work at the office and bunch the distractions.  However it works out for you, the key is to (as much as possible) group your distractions and leave large un-interrupted periods for creative work.&lt;/p&gt;
&lt;p&gt;Distractions can be self-inflicted as well as coming from others.  When I want to get stuff done, I try to listen to familiar music (oftentimes looping a single album for a few days).  I&amp;rsquo;ll also close Slack/Twitter/Email and other distracting apps.  Note that the distinction between mechanical and creative is important here.  When doing mechanical work, I&amp;rsquo;m fine having distractions around.  It&amp;rsquo;s only when I&amp;rsquo;m trying to harness mental energy that I care.&lt;/p&gt;
&lt;h3 id=&#34;day-to-day-work-adds-up&#34;&gt;Day to Day work adds up&lt;/h3&gt;
&lt;p&gt;I&amp;rsquo;m a &lt;a href=&#34;http://blog.codinghorror.com/the-magpie-developer/&#34;&gt;magpie&lt;/a&gt;.  I love shiny new tools, projects, and ideas.  It&amp;rsquo;s very easy for me to get bored with a problem once I feel like I understand it.   I get excited by pouring effort into learning something new, not so much the hard work to finish the last 20% of what I&amp;rsquo;ve started.  What I&amp;rsquo;m slowly learning though is that it is my day-to-day work that makes an impact, not my crazy productivity binges.  Making things that last requires day to day dedication.  That also means maintaining focus.  The easiest way to waste day to day hard work is to spend it on a different thing each day.  There&amp;rsquo;s nothing wrong with trying new things.  But real productivity requires setting some priorities and sticking with them for a while.&lt;/p&gt;
&lt;h3 id=&#34;team-matters-more-than-the-project&#34;&gt;Team matters more than the project&lt;/h3&gt;
&lt;p&gt;Finally, individual productivity doesn&amp;rsquo;t happen in a vacuum.  Who we work with can undermine or boost our results.  I don&amp;rsquo;t believe that it&amp;rsquo;s a small difference either.  I&amp;rsquo;d rather have a great team with no individually brilliant members than a bad team with one or two great programmers any day.  One of &lt;a href=&#34;http://www.windsorcircle.com/about-us/our-values&#34;&gt;Windsor Circle&amp;rsquo;s values&lt;/a&gt; is that teams survive longer than individuals.  The same can be said of their results.  Teams can magnify what is possible for a product.  Any individual has limits on what he or she can create.  Teams allow for those limits to be lifted by building on each others skills. At the same time, teams can limit each other by fighting, mis-communicating, distracting, or pursuing different goals.  So all of the other productivities ideas here can be applied just as well to a team as they do to an individual.  The best work comes from teams consistently working together towards a common goal over a long period of time in a constant and productive environment.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>The Most Interesting Atom Packages I&#39;ve found (so far)</title>
      <link>https://benmccormick.org/2016/01/10/212549.html</link>
      <pubDate>Sun, 10 Jan 2016 22:25:49 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2016/01/11/212549.html</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve been using &lt;a href=&#34;https://atom.io/&#34;&gt;Atom&lt;/a&gt; as my primary text editor for the last 3 months.  I don&amp;rsquo;t completely love it.  There are elements (startup speed, maturity of some core editing components, not being able to run it in a terminal) that I miss from my experiences with Vim and/or Sublime Text.  I&amp;rsquo;m using Atom though because the core editing experience is now &amp;ldquo;good enough&amp;rdquo; and the way the editor is built allows for some very cool and unique experiences.  Atom (like &lt;a href=&#34;https://code.visualstudio.com/&#34;&gt;Visual Studio Code&lt;/a&gt;) is built on &lt;a href=&#34;http://electron.atom.io/&#34;&gt;Electron&lt;/a&gt;, Github&amp;rsquo;s JavaScript environment for building desktop apps.  Because it is built with web technologies and was designed from the beginning to be extensible, it is much easier for most developers to build rich visual extensions on top of Atom that provide unique UIs for editor functions than it is in Sublime Text, Vim, Emacs or an IDE.  The following are some of the &amp;ldquo;most interesting&amp;rdquo; Atom packages I&amp;rsquo;ve found.  Interesting in this case means that they really only could have been done as they are in Atom or a similarly flexible editor.&lt;/p&gt;
&lt;h3 id=&#34;pigments&#34;&gt;Pigments&lt;/h3&gt;
&lt;p&gt;At first use, &lt;a href=&#34;https://github.com/abe33/atom-pigments&#34;&gt;Pigments&lt;/a&gt; seems like a pretty run of the mill color highlighter.  There are similar projects for Sublime Text and Vim that look at color names in a CSS or LESS file and highlight them with the color they represent.&lt;/p&gt;
&lt;img class=&#34;full-width&#34; alt=&#34;pigment-preview&#34; src=&#34;color_less_-__Users_Ben_Code_Windsor_wcui_dev_src_wcui_-_Atom.png&#34;&gt;
&lt;p&gt;But Pigments does much more than that.  In addition to highlighting text, Pigments searches your project and creates a directory of all the colors used in your projects.  You can look through your palette and quickly go to the definition of any individual color.  Because pigments tracks everything, it can highlight LESS/SCSS variables as well as plain color names, even if those variables were originally defined in a different file.  Pigments also hooks into Atom&amp;rsquo;s autocomplete, and displays a preview of the color options when autofilling colors.&lt;/p&gt;
&lt;img class=&#34;full-width&#34; alt=&#34;Pigments project&#34; src=&#34;Palette_-__Users_Ben_Code_Windsor_wcui_dev_src_wcui_-_Atom_and_Editor_-_benmccormick_org.png&#34;&gt;
&lt;p&gt;It is a rich way of managing colors for a whole project, the best way of seeing at a glance every color used in your CSS project that I&amp;rsquo;ve ever seen.&lt;/p&gt;
&lt;h3 id=&#34;expose&#34;&gt;Expose&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://atom.io/packages/expose&#34;&gt;Expose&lt;/a&gt; is a file management tool modeled after Mac OSX&amp;rsquo;s expose feature.  With it, you can instantly display all open files as small thumbnails, and switch quickly between them using the keyboard, which can be super helpful when tabs get out of control.&lt;/p&gt;
&lt;img class=&#34;full-width&#34; alt=&#34;expose&#34; src=&#34;frequency_cap_es6_-__Users_Ben_Code_Windsor_wcui_dev_src_wcui_-_Atom_and_Editor_-_benmccormick_org.png&#34;&gt;
&lt;h3 id=&#34;autocomplete-plus&#34;&gt;Autocomplete-plus&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/atom/autocomplete-plus/&#34;&gt;Autocomplete-plus&lt;/a&gt; started as a community package but has now become part of the core editor.  It&amp;rsquo;s also probably the least unique idea I&amp;rsquo;m listing here.  It&amp;rsquo;s still worth including on this list though, for 2 reasons.  First, autocomplete plus has flexible visual context options, allowing autocomplete providers to show the type of the autocomplete option, a brief description, and potentially a more in depth description.  So users can distinguish between (for instance) completions offering a snippet, a function, a keyword, or an import.&lt;/p&gt;
&lt;img class=&#34;full-width&#34; alt=&#34;autocomplete-plus&#34; src=&#34;frequency_cap_es6_-__Users_Ben_Code_Windsor_wcui_dev_src_wcui_-_Atom.png&#34;&gt;
&lt;p&gt;Autocomplete-plus is also a great example of the flexible nature of Atom.  Because Atom itself is made up of packages, with a very small core package, it&amp;rsquo;s easy to replace key parts of the editor like the auto-complete package with a community version.  And if that version ends up being better in the long run, it&amp;rsquo;s possible to pull that into the editors core, as happened with autocomplete-plus.&lt;/p&gt;
&lt;h3 id=&#34;todo-show&#34;&gt;Todo-show&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://atom.io/packages/todo-show&#34;&gt;Todo-show&lt;/a&gt; is a cool little package that searches your project for comments containing TODO, FIXME, CHANGED, REVIEW and other configurable comment strings, and lists them as a table.  It&amp;rsquo;s a simple idea that formalizes something that many developers do all the time.&lt;/p&gt;
&lt;img class=&#34;full-width&#34; alt=&#34;todo-show&#34; src=&#34;frequency_cap_es6_-__Users_Ben_Code_Windsor_wcui_dev_src_wcui_-_Atom-1.png&#34;&gt;
&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;:  Twitter has pointed out this even crazier riff on this concept that I&amp;rsquo;d seen a while ago but had been unable to find when I dove back into Atom.  &lt;a href=&#34;http://imdone.io/&#34;&gt;Imdone&lt;/a&gt; is a trello-like experience in the editor for managing todos.&lt;/p&gt;
&lt;blockquote class=&#34;twitter-tweet&#34; lang=&#34;en&#34;&gt;&lt;p lang=&#34;en&#34; dir=&#34;ltr&#34;&gt;&lt;a href=&#34;https://twitter.com/_benmccormick&#34;&gt;@_benmccormick&lt;/a&gt; &lt;a href=&#34;https://twitter.com/AtomEditor&#34;&gt;@AtomEditor&lt;/a&gt; You might also like imdone-atom. It&amp;#39;s a drag and drop TODO task board with issue tracking integration!&lt;/p&gt;&amp;mdash; imdone.io (@imdoneIO) &lt;a href=&#34;https://twitter.com/imdoneIO/status/686577997395013633&#34;&gt;January 11, 2016&lt;/a&gt;&lt;/blockquote&gt;
&lt;h3 id=&#34;linter&#34;&gt;Linter&lt;/h3&gt;
&lt;p&gt;Similar to autocomplete-plus, you may think you&amp;rsquo;ve seen &lt;a href=&#34;https://atom.io/packages/linter&#34;&gt;Linter&lt;/a&gt; before.  It&amp;rsquo;s similar to Syntastic for Vim and SublimeLinter for Sublime Text.  But Atom&amp;rsquo;s flexibility allows it to be better than both of those.  Like Syntastic and SublimeLinter, Linter integrates with many different linting providers to show errors and warnings that tools pick up on through static analysis in files.  But rather than being limited to the line-by-line gutter warnings or showing collections of warnings through awkward use of UI elements meant for a different purpose, Linter shows you a live collection of errors at the bottom of the file and lets you easily switch back and forth between that and errors for all open project files.&lt;/p&gt;
&lt;img class=&#34;full-width&#34; alt=&#34;linter&#34; src=&#34;frequency_cap_es6_-__Users_Ben_Code_Windsor_wcui_dev_src_wcui_-_Atom-2.png&#34;&gt;
&lt;h3 id=&#34;git-time-machine&#34;&gt;git-time-machine&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/littlebee/git-time-machine&#34;&gt;git-time-machine&lt;/a&gt; is the newest package on this list.  It&amp;rsquo;s only a month old, but is quite possibly my favorite example of Atom&amp;rsquo;s potential.  After setting it up, you can use a keyboard shortcut to see a bubble plot of that files git history, and then hover to see the commit messages, and click to see an old version of the file.  It is the most accessible UI I&amp;rsquo;ve ever seen for working with git history.&lt;/p&gt;
&lt;img class=&#34;full-width&#34; alt=&#34;time-machine&#34; src=&#34;Fullscreen_1_10_16__9_24_PM.png&#34;&gt;
</description>
    </item>
    
    <item>
      <title>Reusable Code Patterns</title>
      <link>https://benmccormick.org/2016/01/08/002229.html</link>
      <pubDate>Fri, 08 Jan 2016 01:22:29 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2016/01/08/002229.html</guid>
      <description>&lt;p&gt;One of the most repeated mantras in all of software is the term &amp;ldquo;Don&amp;rsquo;t Repeat Yourself&amp;rdquo;. The phrase was first popularized by the book &lt;a href=&#34;http://www.amazon.com/Pragmatic-Programmer-Journeyman-Master/dp/020161622X/ref=sr_1_1?s=books&amp;amp;ie=UTF8&amp;amp;qid=1452230454&amp;amp;sr=1-1&amp;amp;keywords=pragmatic+programmer&#34;&gt;The Pragmatic Programmer&lt;/a&gt;, with it&amp;rsquo;s call for DRY software.  At it&amp;rsquo;s core, DRY is all about finding a way to keep logic related to a particular function in one place, so that changes for new functionality can be limited in scope and have predictable consistent effects.  Software developers are usually very good at knowing that repetition is bad, but I&amp;rsquo;ve seen that we can be less great at communicating about our options to avoid it, or discussing the tradeoffs between different approaches.  This post is going to look at a specific situation that programmers encounter all the time, and give a framework for talking about how to handle it, focusing on positive options rather than simply what we want to avoid.&lt;/p&gt;
&lt;p&gt;The high level situation I want to talk about is when a programmer encounters a problem for which they have an existing piece of code that mostly works as a solution, but doesn&amp;rsquo;t quite meet all the requirements.  Some examples would include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;a screen that is required to show a user avatar, but at a different size than other avatars displayed in the interface (all of which use an existing avatar ui widget)&lt;/li&gt;
&lt;li&gt;a program that already has an API to get friends data from a users Facebook account, and needs to add a second API to get similar data from their Twitter account&lt;/li&gt;
&lt;li&gt;a program that needs a  function that takes an integer or a string and displays it on the screen, when it already has a function that displays data but only accepts strings&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Some of those are simple, some are more complex, and you might already be thinking about how you&amp;rsquo;d handle each case.  The point isn&amp;rsquo;t so much the exact example so much as having a way to communicate what the options are.  I&amp;rsquo;m going to lay out 6 different patterns for handling situations where you&amp;rsquo;re required to implement something similar but not exactly the same as something that already exists.  I will not be endorsing a particular strategy as correct, since they all have their place.  Instead I&amp;rsquo;ll be discussing the benefits and risks of each, and hopefully giving a good framework for thinking about and discussing these tradeoffs in the future.&lt;/p&gt;
&lt;h3 id=&#34;using-the-existing-component-as-is&#34;&gt;Using the existing component as is&lt;/h3&gt;
&lt;h4 id=&#34;pros&#34;&gt;Pros&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Least Effort&lt;/li&gt;
&lt;li&gt;Encourages consistency and simplicity&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;cons&#34;&gt;Cons&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Often not allowed&lt;/li&gt;
&lt;li&gt;May be compromising user experience for developer expediency&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The first option is the simplest.  If you have a component that is similar to what is required but doesn&amp;rsquo;t quite match the requirements, change the requirements.  This can make sense in situations like the avatar example above, when you have a UI element or control that you use everywhere in the system.  It may make sense to use that same element in a new place for the benefit of consistency and user knowledge, rather than inventing a new UI element for the page.  This obviously requires an environment where developer input is welcome in the design and requirements process.&lt;/p&gt;
&lt;p&gt;Developers should be cautious with this though.  If using an existing component removes unecessary complexity from the design and saves time, it&amp;rsquo;s a win-win.  But if the design was a good one, and users lose out on functionality through developer &amp;ldquo;efficiency&amp;rdquo;, it can hurt the product.  Even worse, decisions like that usually end up coming back round again, as the need that was ignored often will pop up in new situations.&lt;/p&gt;
&lt;h3 id=&#34;copy-and-paste&#34;&gt;Copy and Paste&lt;/h3&gt;
&lt;h4 id=&#34;pros-1&#34;&gt;Pros&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Simple&lt;/li&gt;
&lt;li&gt;Keeps existing code stable in the short term&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;cons-1&#34;&gt;Cons&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Adds to maintenance burden&lt;/li&gt;
&lt;li&gt;Decreases readability/understandability of the code base for other developers&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is the approach that says &amp;ldquo;To Hell with DRY&amp;rdquo;, and takes some existing code, creates a copy of it, and then partially modifies it to suit the current situation.  This would be analogous to taking the User avatar code listed above, creating a copy of it and simply modifying it to be bigger.  That might look like this in CSS:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;.user-avatar {
    height: 30px;
    width: 30px;
    padding:5px;
    float: left;
    border-radius: 5px;
}

.user-avatar-big {
    height: 50px;
    width: 50px;
    padding:5px;
    float: left;
    border-radius: 10px;
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Everything now works exactly the way we want it.  The problem comes when somebody wants to change the floats on avatar elements, or add a border to all of them now.  Instead of being able to make one change, they have to be aware of both avatar versions, and modify both.&lt;/p&gt;
&lt;p&gt;Note that copy and paste isn&amp;rsquo;t always bad.  Often there are very good reasons for not modifying existing code.  It may be code that you don&amp;rsquo;t control (for instance forking an open source project that is not actively maintained to add a feature that you want), or code that is from another project (or from a legacy portion of the current project that is handled as a different code base).  DRY is not crazy advice though, and if you&amp;rsquo;re operating within a single codebase you control, this is usually not the best option.&lt;/p&gt;
&lt;h3 id=&#34;classical-inheritance&#34;&gt;Classical Inheritance&lt;/h3&gt;
&lt;h4 id=&#34;pros-2&#34;&gt;Pros&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Well understood by most programmers, especially those with an academic background&lt;/li&gt;
&lt;li&gt;fits very well when you have multiple things that are variations of a type, with more similarities than differences&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;cons-2&#34;&gt;Cons&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Often used as a silver bullet for all situations&lt;/li&gt;
&lt;li&gt;Not suitable for situations where the objects are more different than similar, or when they are 2 different things at the core with shared behavior&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you ask a recent Computer Science graduate what the best way to solve the problem of similar behavior across objects is, 99% of them will immediately say &lt;a href=&#34;https://en.wikipedia.org/wiki/Inheritance_(object-oriented_programming)&#34;&gt;inheritance&lt;/a&gt;.  The &amp;ldquo;conventional wisdom&amp;rdquo; that&amp;rsquo;s taught in most introductory computer science courses is that Object Oriented Programming is the best way to structure programs, and that Object Oriented programming is primarily about inheritance.  Both statements are shaky, but the prevalence of this mindset means that many developers come out of school and look at every problem they see as a nail to hit with their inheritance hammer (this is certainly something I was guilty of when I first graduated).&lt;/p&gt;
&lt;p&gt;Inheritance isn&amp;rsquo;t bad.  It&amp;rsquo;s definitely a tool you want in your toolbox, and shallow hierarchies of objects that inherit from a base class are a great pattern.  90% of &amp;ldquo;Frameworks&amp;rdquo; out there (Backbone, React, django, Rails, etc) use some form of inheritance as a way of structuring how users interact with the framework.  But when it is your only tool, things get ugly quickly.&lt;/p&gt;
&lt;p&gt;Inheritance is a bad choice when 2 objects are mostly different.  Inheritance forces objects to share an API, and implies that objects can be used interchangeably.  If the objects aren&amp;rsquo;t really interchangeable, this can lead to jumping through hoops to maintain a shared API, with a small base class being stretched between 2 or more verbose child classes.  Interfaces especially tend to be bad places to use inheritance, as they tend to require small tweaks and differences when used in different places that aren&amp;rsquo;t friendly to being passed as configuration properties or over-ridden methods.&lt;/p&gt;
&lt;h3 id=&#34;configuration&#34;&gt;Configuration&lt;/h3&gt;
&lt;h4 id=&#34;pros-3&#34;&gt;Pros&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Keeps everything in a single place&lt;/li&gt;
&lt;li&gt;Declarative configuration can be easier to read and update than a bunch of logic&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;cons-3&#34;&gt;Cons&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Can get out of hand fast as use cases increase&lt;/li&gt;
&lt;li&gt;Often unclear what defaults should be, bad defaults make common use cases verbose&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We can define separate behaviors for 2 similar things by using a single configurable object. This maximizes code re-use since everything is in one place, and provides an easy to read abstraction over the code for quick changes later.  However, like inheritance it works much better for similar objects with small differences rather than different objects with shared behaviors, and can lead to &amp;ldquo;configuration creep&amp;rdquo; when the differences slowly grow, creating a monster configuration and spaghetti code that tries to handle all of the possible configuration options it could be passed.&lt;/p&gt;
&lt;p&gt;A big design point with configuration based strategies is figuring out good defaults.  If an object is designed so that the default case requires minimal to no configuration, and only true edge cases require a lot of configuration, configuration based objects and APIs can be very pleasant to deal with.  But objects with bad or no defaults that require common cases to include extensive configuration eventually lead to bloated projects that are very difficult to debug.&lt;/p&gt;
&lt;h3 id=&#34;mixins&#34;&gt;Mixins&lt;/h3&gt;
&lt;h4 id=&#34;pros-4&#34;&gt;Pros&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Share individual behaviors or attributes well&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;cons-4&#34;&gt;Cons&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Can break down when the behavior or attribute requires significant knowledge about the object&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In contrast to inheritance and configuration, &lt;a href=&#34;https://en.wikipedia.org/wiki/Mixin&#34;&gt;mixins&lt;/a&gt; work well when objects are significantly different, but share similar behaviors. &lt;code&gt;Mixins&lt;/code&gt; are the strategy of adding individual methods or properties to an object without implying any relationship between objects that use it.  Mixins are great when used to add a standalone behavior to different objects.  They avoid the problems of inheritance and don&amp;rsquo;t lock an object into a single API.&lt;/p&gt;
&lt;p&gt;That said, it can often be hard to construct good mixins, since many behaviors require knowledge of the object that is performing the behavior, such as making assumptions about the structure of the objects data.  This either requires the objects implementing the mixin to obey rules about how they&amp;rsquo;re structured, similar to inheritance, involves offloading significant complexity into the mixin to allow it to handle different formats (making it a potential source of bugs), or it risks naming conflicts if the mixin tries to implement the data storage itself.&lt;/p&gt;
&lt;h3 id=&#34;composition&#34;&gt;Composition&lt;/h3&gt;
&lt;h4 id=&#34;pros-5&#34;&gt;Pros&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Incredibly flexible for handling subtly different behaviors&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;cons-5&#34;&gt;Cons&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Can ramp up complexity, making it difficult to see the whole system&lt;/li&gt;
&lt;li&gt;May end up pushing code re-use problems downwards instead of solving them, leading to many small similar modules&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Often when faced with 2 similar objects or functions, the best solution is to create more objects or functions.  Composition is trendy these days.  On the server side, you have people talking up micro-services and programs composed of small single-purpose modules.  On the client, React is the hottest library around.  The idea is appealing.  Instead of having one big complicated &amp;ldquo;thing&amp;rdquo;, I can create a few smaller &amp;ldquo;things&amp;rdquo; that I can wrap my mind around, and then get them to work together.  When this works well its great.  React for example, makes testing UIs much easier, since you can unit test individual components in a reliable way.  The problem is that it often moves complexity out of the components and into the architecture.  The hard part becomes figuring out how components fit together, designing interfaces and deciding what should be going where.  Although any individual piece of code may be comprehensible and simple, the system at large is harder to visualize and understand.&lt;/p&gt;
&lt;p&gt;Like mixins, composition often works best when you have 2 or more fairly different &amp;ldquo;things&amp;rdquo; that share behavior.  The composition mindset is to treat code like lego blocks that you can snap together in different configurations as needed.  When done well, it allows for useful abstraction, letting developers create complex components out of meaningful sub-components without having to know all the details of the subcomponents.  When done poorly, it can lead to a fractured project with many undocumented dependencies between components.&lt;/p&gt;
&lt;h2 id=&#34;all-together-now&#34;&gt;All Together Now&lt;/h2&gt;
&lt;p&gt;The great thing about these strategies is that none of them is the &lt;strong&gt;right answer&lt;/strong&gt;.  All of them have their place, and can even be combined.  At my work we&amp;rsquo;ve developed code for describing workflows.  The workflows are described using an object that takes a configuration and uses it to layout a series of widgets.  Each widget inherits from a framework, and many of them use mixins to share behavior.  Most of the widgets are composed of several smaller views, and as developers we have pushed back against designs several times in order to allow greater widget re-use.  Each time we need to create a new automator we&amp;rsquo;ve started by copy and pasting some of the configuration boilerplate (which hopefully we&amp;rsquo;ll reduce going forward by providing better default behavior as we understand the requirements better). This is one feature of a large software product, and it uses all 6 reuse patterns I&amp;rsquo;ve described to perform its purpose.&lt;/p&gt;
&lt;p&gt;In the end, what I hope you as a reader get out of this is not that one strategy is good or bad.  Instead I want to provide a way of thinking about the choices around re-use, so that we as developers can talk intelligently about the options and tradeoffs and make the right choice for a given situation.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>2015 Roundup</title>
      <link>https://benmccormick.org/2015/12/31/005604.html</link>
      <pubDate>Thu, 31 Dec 2015 01:56:04 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2015/12/31/005604.html</guid>
      <description>&lt;p&gt;Thanks to all of you who have followed my blog this year. More people visited the blog this year than in its previous 2 years of existence combined.  I&amp;rsquo;m excited to continue writing and starting conversations in 2016.&lt;/p&gt;
&lt;h3 id=&#34;most-read-posts-of-2015&#34;&gt;Most Read Posts of 2015&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;http://benmccormick.org/2015/09/09/what-can-backbone-developers-learn-from-react/&#34;&gt;What Backbone Developers Can Learn From React&lt;/a&gt; - A look at lessons that Backbone developers can take from the React community.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;http://benmccormick.org/2015/01/26/backbone-radio/&#34;&gt;Building Modular Web Apps With Backbone.Radio&lt;/a&gt; - A deep dive into Backbone.Radio, a messaging system for Backbone and Marionette applications.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;http://benmccormick.org/2015/09/14/es5-es6-es2016-es-next-whats-going-on-with-javascript-versioning/&#34;&gt;ES5, ES6, ES2016, ES.Next: What&amp;rsquo;s going on with JavaScript versioning?&lt;/a&gt; - An explanation of the weird and confusing naming conventions for JavaScript versions&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;http://benmccormick.org/2015/04/07/es6-classes-and-backbone-js/&#34;&gt;Why Backbone.js and ES6 Classes don&amp;rsquo;t mix&lt;/a&gt; - An examination of the problems that developers face trying to use ES6 classes and Backbone together.  A &lt;a href=&#34;http://benmccormick.org/2015/07/06/backbone-and-es6-classes-revisited/&#34;&gt;followup article&lt;/a&gt; explored some potential solutions.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;code-i-wrote-in-2015&#34;&gt;Code I wrote in 2015&lt;/h3&gt;
&lt;p&gt;Most of the code I wrote this year was for my work at Windsor Circle and on a React based side project that is not yet ready for prime time.  But I did get&lt;/p&gt;
&lt;p&gt;to release a small &lt;a href=&#34;http://benmccormick.org/2015/05/25/marionette-service-service-objects-for-marionette/&#34;&gt;service library&lt;/a&gt; for Marionette developers, and made several contributions to the core Marionette library.&lt;/p&gt;
&lt;h3 id=&#34;languages-and-libraries-i-started-using-in-2015&#34;&gt;Languages and Libraries I started using in 2015&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://babeljs.io/&#34;&gt;Babel&lt;/a&gt; has had by far the biggest impact on my code in 2015.  Being able to write modern JavaScript without compatibility concerns has been a breath of fresh air&lt;/li&gt;
&lt;li&gt;My team switched from Underscore to &lt;a href=&#34;https://lodash.com/&#34;&gt;lodash&lt;/a&gt; at the end of 2014, and I&amp;rsquo;ve been using it a lot more this year.  Like Babel, it changes the way I write code.&lt;/li&gt;
&lt;li&gt;I don&amp;rsquo;t use it day to day, but I&amp;rsquo;ve loved playing with &lt;a href=&#34;https://facebook.github.io/react/&#34;&gt;React&lt;/a&gt; and &lt;a href=&#34;https://github.com/rackt/redux&#34;&gt;Redux&lt;/a&gt;.  I think UI as a pure function of state with a defined set of user actions/mutations is the future.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;languages-and-libraries-i-stopped-using-in-2015&#34;&gt;Languages and Libraries I stopped using in 2015&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;With ES6 becoming a valid option, I&amp;rsquo;ve moved on from &lt;a href=&#34;http://coffeescript.org/&#34;&gt;Coffeescript&lt;/a&gt;.  It&amp;rsquo;s a beautiful, non-standard language that is never going to develop the tooling that is building up around the standard JavaScript language.&lt;/li&gt;
&lt;li&gt;I haven&amp;rsquo;t stopped using &lt;a href=&#34;http://jquery.com/&#34;&gt;jQuery&lt;/a&gt;, since Marionette uses it for event handling and ajax, but I&amp;rsquo;ve begun looking at direct jQuery-style DOM manipulation as a code smell&lt;/li&gt;
&lt;li&gt;This mainly happened early in 2014, but 2015 was the first year I didn&amp;rsquo;t write a single line of Java.  I haven&amp;rsquo;t missed it.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;languages-and-libraries-i-used-more-or-less-every-day-in-2015&#34;&gt;Languages and Libraries I used (more or less) every day in 2015&lt;/h3&gt;
&lt;p&gt;JavaScript (ES6), Python, Backbone, Marionette, lodash&lt;/p&gt;
&lt;h3 id=&#34;languages-and-libraries-i-want-to-try-in-2016&#34;&gt;Languages and Libraries I want to try in 2016&lt;/h3&gt;
&lt;p&gt;Elm or ClojureScript, Rust or Go, Flow, Ember, Pandas and other python data analysis libraries&lt;/p&gt;
&lt;h3 id=&#34;blogs-i-started-following-in-2015&#34;&gt;Blogs I started following in 2015&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://www.2ality.com/&#34;&gt;2ality&lt;/a&gt; is a great blog by Axel Rauschmayer focused on the JavaScript language&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://rauchg.com/essays&#34;&gt;rauchg.com&lt;/a&gt; is not updated often, but all 3 posts so far have been fantastic&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://raganwald.com/&#34;&gt;raganwald.com&lt;/a&gt; is a great resource for functional programming fans who write JavaScript&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;blogs-i-read-every-post-from-in-2015&#34;&gt;Blogs I read every post from in 2015&lt;/h3&gt;
&lt;p&gt;Rands In Repose, Stratechery, Marco.org, rauchg.com, Little Big Details, Bull City Rising&lt;/p&gt;
&lt;h3 id=&#34;software-i-started-using-in-2015&#34;&gt;Software I started using in 2015&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;I started using &lt;a href=&#34;https://atom.io/&#34;&gt;Atom&lt;/a&gt; this fall as my primary code editor.  There are things about it I like less than Vim or Sublime Text, but it&amp;rsquo;s configurability and the fact that people have used it to make beautiful, intuitive UIs for tools that I use have sold me for now.  I still use Vim on a regular basis when I want to stay in the terminal, and am keeping an eye on &lt;a href=&#34;https://neovim.io/&#34;&gt;Neovim&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://www.ghostery.com/&#34;&gt;Ghostery&lt;/a&gt; is a fantastic ad blocker that focuses on transparency, showing you the ad networks and trackers that are running on a page and allowing you to selectively block ad networks or sites, helpful for those of us who want to support sites we use and allow analytics but are overwhelmed by the slimy, slow state of the web.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://overcast.fm/&#34;&gt;Overcast&lt;/a&gt; is a great podcast app for iOS that has convinced me to start listening to podcasts.  (I&amp;rsquo;ve enjoyed &lt;a href=&#34;https://changelog.com/podcast/&#34;&gt;The Changelog&lt;/a&gt;, &lt;a href=&#34;http://exponent.fm/&#34;&gt;Exponent&lt;/a&gt;, and &lt;a href=&#34;https://serialpodcast.org/&#34;&gt;Serial&lt;/a&gt;).&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;software-i-stopped-using-in-2015&#34;&gt;Software I stopped using in 2015&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.mailboxapp.com/&#34;&gt;Mailbox&lt;/a&gt;: RIP&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.onenote.com/&#34;&gt;OneNote&lt;/a&gt;: I made an effort to switch from Evernote to OneNote this summer, but it failed because it&amp;rsquo;s much harder to get stuff into OneNote for those of us who live in Apple-Land.  Not enough integrations&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;software-i-used-nearly-every-day-in-2015&#34;&gt;Software I used (nearly) every day in 2015&lt;/h3&gt;
&lt;p&gt;OSX/iOS, Google Search, Chrome/Safari, Gmail, Twitter/Tweetbot, Feedbin/Reeder, Instapaper, iMessage, Slack, Trello, 1Password, Atom/Vim, iTerm, Fish Shell, tmux, Bitbucket, Fantastical&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>ES6 Patterns: Converting Callbacks to Promises</title>
      <link>https://benmccormick.org/2015/12/29/223047.html</link>
      <pubDate>Tue, 29 Dec 2015 23:30:47 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2015/12/30/223047.html</guid>
      <description>&lt;div class=&#34;explanation&#34;&gt;
I&#39;ve been writing code using the new features defined in the ECMAScript 2015 version of JavaScript (&lt;a href=&#34;http://benmccormick.org/2015/09/14/es5-es6-es2016-es-next-whats-going-on-with-javascript-versioning/&#34;&gt;more commonly known as ES6&lt;/a&gt;) since January.  Throughout the year I&#39;ve seen myself start using a few new patterns that I think make my code better.  I&#39;m going to share them here with a few quick hitter articles.  If you missed it, I wrote about &lt;a href=&#34;http://benmccormick.org/2015/11/30/es6-patterns-clean-higher-order-functions/&#34;&gt;clean higher order functions&lt;/a&gt; earlier this week.  This post focuses on working with asynchronous code in ES6.  
&lt;/div&gt;
&lt;h3 id=&#34;background&#34;&gt;Background&lt;/h3&gt;
&lt;p&gt;One of the nicest new features of ES6 JavaScript is the standardization of Promises.  Promises are a method for managing asynchronous code that serve as an alternative to the standard callback function syntax that has been the JavaScript standard for years.  If you&amp;rsquo;re unfamiliar with them, a good example of a Promise based API is the new &lt;code&gt;fetch&lt;/code&gt; api provided by browsers.  &lt;code&gt;fetch&lt;/code&gt; is a replacement for the older callback based XMLHttpRequest API.  A quick example of an HTTP request with the 2 APIs provides a nice comparison of how Promises can lead to clearer code.&lt;/p&gt;
&lt;p&gt;A simple get request with XMLHttpRequest looks like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt; reqListener() {  
  &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; data &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; JSON.parse(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.responseText);  
  console.log(data);  
}

&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt; reqError(err) {  
  console.log(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Fetch Error :-S&amp;#39;&lt;/span&gt;, err);  
}

&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; request &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; XMLHttpRequest();  
request.onload &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;() {
  &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; data &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; JSON.parse(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.responseText);  
  &lt;span style=&#34;color:#6272a4&#34;&gt;//do stuff with data
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;};  

request.onerror &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;() {
    alert(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;There was a problem with the request&amp;#39;&lt;/span&gt;);
}
request.open(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;get&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;/api/foo/bar&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#ff79c6&#34;&gt;true&lt;/span&gt;);  
request.send();
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;whereas with fetch we get this instead&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;fetch(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;/api/foo/bar&amp;#39;&lt;/span&gt;).then(&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(data) {
    &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; data.json();
}).then(&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(jsonData) {
    &lt;span style=&#34;color:#6272a4&#34;&gt;//do stuff with the data
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;}).&lt;span style=&#34;color:#ff79c6&#34;&gt;catch&lt;/span&gt;(&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(e) {
    alert(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;There was a problem with the request&amp;#39;&lt;/span&gt;);
})
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is admittedly a slightly unfair example due to XMLHttpRequest&amp;rsquo;s clunky object oriented API, but the key take away here is that promises allow for easier visualization of a program&amp;rsquo;s flow, as well as the ability to easily chain both synchronous and asynchronous operations together into a unified API.&lt;/p&gt;
&lt;p&gt;Promises have been around for a little while in user-land.  There are a bunch of Promise libraries out there that eventually standardized on a spec called &lt;code&gt;Promises/A+&lt;/code&gt;.  Promises/A+ compliant libraries include &lt;a href=&#34;https://github.com/kriskowal/q&#34;&gt;Q&lt;/a&gt;, &lt;a href=&#34;https://github.com/petkaantonov/bluebird&#34;&gt;Bluebird&lt;/a&gt;, and &lt;a href=&#34;https://github.com/tildeio/rsvp.js&#34;&gt;rsvp&lt;/a&gt;.  There are also many older libraries that provide Promise-like capabilities but are not completely spec compatible, most notably &lt;a href=&#34;https://api.jquery.com/category/deferred-object/&#34;&gt;jQuery deferreds&lt;/a&gt;.  But with ES6 Promises are being standardized.  Happily, since the implementation uses the standard that user-land libaries have agreed upon, the Promise spec is compatible with existing implementations, and existing code bases can remove their existing libraries in favor of the browser supplied version, or have code written to use the browser version interop cleanly with their existing code.  Support for Promises now exists in the latest versions of all major browsers, but it never made it to Internet Explorer and is Edge only for Microsoft browsers.  So most developers will still want to consider using a polyfill for the time being.&lt;/p&gt;
&lt;h3 id=&#34;converting-callback-driven-code-to-use-promises&#34;&gt;Converting callback-driven code to use Promises&lt;/h3&gt;
&lt;p&gt;If you believe that Promises are worthwhile, you&amp;rsquo;ll immediately encounter a problem in today&amp;rsquo;s JavaScript world.  Many JavaScript APIs, including most standard browser APIs and older but still popular libraries like jQuery and Backbone are heavily callback driven.  Rather than mixing 2 different styles of asynchronous code, wouldn&amp;rsquo;t it be nice if we could easily convert callback-based APIs to use Promises?  It turns out that it&amp;rsquo;s not that hard.  Let&amp;rsquo;s take the simplest example possible to start.  &lt;code&gt;setTimeout&lt;/code&gt; is a straightforward browser API that waits for a specified period of time and then executes a callback.  A standard use looks like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt; doStuff() {&lt;span style=&#34;color:#6272a4&#34;&gt;/*...*/&lt;/span&gt;}

setTimeout(doStuff, &lt;span style=&#34;color:#bd93f9&#34;&gt;300&lt;/span&gt;);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A Promise-based API for this function would likely look something like this code.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;timeout(&lt;span style=&#34;color:#bd93f9&#34;&gt;300&lt;/span&gt;).then(doStuff)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We can create an API like that using setTimeout.  To do that, we&amp;rsquo;ll need a function &lt;code&gt;timeout&lt;/code&gt; which takes a timeout variable and returns a Promise.&lt;/p&gt;
&lt;p&gt;You can define A+ compliant Promises using the Promise constructor, which expects a single function as an argument.  That function takes 2 arguments, a &lt;code&gt;resolve&lt;/code&gt; function and a &lt;code&gt;reject&lt;/code&gt; function.  The wonderful thing is that under the covers these are just callback functions that the Promise api glosses over.&lt;/p&gt;
&lt;p&gt;Since we already have an API that can handle callbacks, the implementation of our &lt;code&gt;timeout&lt;/code&gt; function is pretty simple.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt; timeout(delay) {
    &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;Promise&lt;/span&gt;(&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(resolve, reject) {
        setTimeout(resolve, delay);
    });
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We don&amp;rsquo;t use the reject callback, since setTimeout doesn&amp;rsquo;t provide any hooks for an error state. So we pass resolve as the callback to setTimeout, and that is all we need.  Now we have a great chainable setTimeout function that we could include in a Promise chain.&lt;/p&gt;
&lt;p&gt;Moving on to a more complicated example, let&amp;rsquo;s take our &lt;code&gt;XMLHttpRequest&lt;/code&gt; code from above and see if we can create a simplified version of the &lt;code&gt;fetch&lt;/code&gt; API using &lt;code&gt;XMLHttpRequest&lt;/code&gt; under the covers.  In this case I&amp;rsquo;m going to use ES6 style arrow functions to reduce the boilerplate a bit.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; fetch &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; (url, options &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {method&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;get&amp;#39;&lt;/span&gt;}) =&amp;gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;Promise&lt;/span&gt;((resolve, reject) =&amp;gt; {
    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; request &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; XMLHttpRequest();  
    request.onload &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; resolve
    request.onerror &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; reject;
    request.open(options.method, url, &lt;span style=&#34;color:#ff79c6&#34;&gt;true&lt;/span&gt;);  
    request.send();
});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is a simplified implementation that doesn&amp;rsquo;t come close to covering all the use cases of fetch, but it provides a great example of how simple it can be to transform a callback based api to a Promise based one, without having to rewrite the existing code&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;For what it&amp;rsquo;s worth, it is equally easy to convert functions in the other direction.  For instance a callback based implementation of fetch can be a one liner.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; callbackFetch &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; (url, options, succ, err) =&amp;gt; fetch(url, options).then(succ).&lt;span style=&#34;color:#ff79c6&#34;&gt;catch&lt;/span&gt;(err);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It&amp;rsquo;s useful to know that the various syntaxes for asynchronous code in JavaScript are effectively equivalent and interoperable.  When designing APIs for your code, both for public libraries with external libraries and components that you use in an application, these patterns can be useful for providing a consistent API, even if you&amp;rsquo;re using code under the covers that presents it&amp;rsquo;s asynchronous code in a different way than your API.&lt;/p&gt;
&lt;h3 id=&#34;more-resources&#34;&gt;More Resources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The free online version of Exploring ES6 by Axel Rauschmayer has a &lt;a href=&#34;http://exploringjs.com/es6/ch_promises.html&#34;&gt;great chapter&lt;/a&gt; on ES6 Promises explaining the API and how they fit in with the A+ standard.&lt;/li&gt;
&lt;li&gt;There was also a &lt;a href=&#34;http://blogs.msdn.com/b/eternalcoding/archive/2015/09/30/javascript-goes-to-asynchronous-city.aspx&#34;&gt;great post by David Catuhe on one of the MSDN blogs&lt;/a&gt; earlier this year highlighting how asynchronous code has evolved in JavaScript over the years, including a look at the new &lt;code&gt;async/await&lt;/code&gt; patterns proposed for ES2016.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;footnotes&#34;&gt;
&lt;ol&gt;
    &lt;li class=&#34;footnote&#34; id=&#34;fn:1&#34;&gt;
        &lt;p&gt;
        And even a full implementation of fetch using XMLHttpRequest is only&lt;a href=&#34;https://github.com/github/fetch/blob/master/fetch.js&#34;&gt; ~300 lines&lt;/a&gt;
        &lt;/p&gt;
        &lt;a href=&#34;#fnref:1&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>ES6 Patterns: Clean Higher Order Functions</title>
      <link>https://benmccormick.org/2015/11/30/000603.html</link>
      <pubDate>Mon, 30 Nov 2015 01:06:03 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2015/11/30/000603.html</guid>
      <description>&lt;div class=&#34;explanation&#34;&gt;
I&#39;ve been writing code using the new features defined in the ECMAScript 2015 version of JavaScript (&lt;a href=&#34;http://benmccormick.org/2015/09/14/es5-es6-es2016-es-next-whats-going-on-with-javascript-versioning/&#34;&gt;more commonly known as ES6&lt;/a&gt;) since January.  Throughout the year I&#39;ve seen myself start using a few new patterns that I think make my code better.  I&#39;m going to share them here with a few quick hitter articles, starting with a simpler way of writing higher order functions
&lt;/div&gt;
&lt;p&gt;A higher order function is a function that either&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Takes another function as an argument or&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Returns a function when called&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Although many people have never heard of them, higher order functions are a key part of JavaScript development and something that most JavaScript developers will encounter every day, whether they know the term or not.  jQuery, Underscore, and many other JavaScript libraries are built on higher order functions.  Many of the core JavaScript APIs, like map, filter, forEach, and setTimeout are functions that take functions as arguments.  If you&amp;rsquo;re not comfortable with these patterns, learning about them can help you understand the JavaScript ecosystem better.  Hopefully this article will pique your interest.&lt;/p&gt;
&lt;p&gt;For this pattern, I&amp;rsquo;ll be focused on the second class of higher-order functions, functions that return other functions.  They can be useful in a variety of cases.  As an example, let&amp;rsquo;s consider a blog commenting application with a list of users.  Our task is to get a list of comments for each user.  We can do that with the builtin &lt;code&gt;map&lt;/code&gt; and &lt;code&gt;filter&lt;/code&gt; functions and a simple helper function like this.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; { commentList } from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;./comments&amp;#39;&lt;/span&gt;;

&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt; getCommentFromUser(userId) {
    &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; {
        user&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; userId,
        comments&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;commentList.filter(&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt; (comment) {
            &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; comment.user &lt;span style=&#34;color:#ff79c6&#34;&gt;===&lt;/span&gt; userId
        },
    };
}

&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; userIds &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; [&lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;, &lt;span style=&#34;color:#bd93f9&#34;&gt;4&lt;/span&gt;, &lt;span style=&#34;color:#bd93f9&#34;&gt;5&lt;/span&gt;],
    userComments &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; userIds.map(getCommentFromUser);

&lt;span style=&#34;color:#6272a4&#34;&gt;//do stuff with comments
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We&amp;rsquo;ve now written some simple, working code.  We take a list of user ids and return a list of users with the ids mapped to their comments.  Everything is fine, and we can move forward to do things with the comments.  If we don&amp;rsquo;t need to maintain this code base, we could probably stop here.&lt;/p&gt;
&lt;p&gt;The problem is, while this example works for the simple case, it isn&amp;rsquo;t very flexible.  We pull the comments directly from a single source that we&amp;rsquo;ve made available to all of the code in our module.  We can&amp;rsquo;t add any additional filters on the comments used or pull comments from additional sources without rewriting our mapping logic. If we decide we only want comments that were written in the past year for instance, we&amp;rsquo;ll need to rewrite our function or mutate commentList in a way that could effect code in the rest of the file. That feels pretty sloppy, since mapping comments to users should be unrelated to determining what comments we&amp;rsquo;re including in our groupings.  Fortunately we can solve this using a higher order function.  If we rewrite the code so that &lt;code&gt;getCommentFromUser&lt;/code&gt; takes a list of comments and returns a function that takes an id, we can then control exactly what comments are included in the grouping.  For now we&amp;rsquo;ll leave our full list, but it could be rewritten later to be a filtered list or to pull comments from multiple sources, without re-writing this logic.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; { commentList } from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;./comments&amp;#39;&lt;/span&gt;;

&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt; getCommentFromUser (comments)
    &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt; (userId) {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; {
            user&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; userId,
            comments&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; comments.filter(&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt; (comment) {
                &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; comment.user &lt;span style=&#34;color:#ff79c6&#34;&gt;===&lt;/span&gt; userId
            },
        };
    }
}

&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; userIds &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; [&lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;, &lt;span style=&#34;color:#bd93f9&#34;&gt;4&lt;/span&gt;, &lt;span style=&#34;color:#bd93f9&#34;&gt;5&lt;/span&gt;],
    userComments &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; userIds.map(getCommentFromUser(commentList));

&lt;span style=&#34;color:#6272a4&#34;&gt;//do stuff with comments
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Our code has gotten much more flexible, but at the cost of readability.  Most developers without significant functional programming experience will have to look twice at the 4 levels of nesting and multiple return statements in our helper function definition to understand what is going on.  We&amp;rsquo;ve added significant boilerplate in a way that muddies up the meaning of our function, when all we&amp;rsquo;re really trying to do is provide a way to make the comments list used in the function configurable.  That is extremely &amp;ldquo;beginner-unfriendly&amp;rdquo;.  At the same time using higher order functions like this is a useful pattern that serves a real need in the design of our application.  Fortunately, ES6 gives us the opportunity to clean up our syntax.&lt;/p&gt;
&lt;p&gt;ES6 provides &amp;ldquo;arrow functions&amp;rdquo;, a shorthand for functions that have 2 main differences from the JavaScript &lt;code&gt;function&lt;/code&gt; keyword.  First, they don&amp;rsquo;t bind a &lt;code&gt;this&lt;/code&gt; value as a context, instead using the &lt;code&gt;this&lt;/code&gt; of the parent scope.  Secondly, they can be written inline, with no parentheses and an implicit return.  So you can write a squaring function as &lt;code&gt;const square = (x) =&amp;gt; x * x;&lt;/code&gt;.  The first property of these functions has many consequences that have been covered in depth elsewhere around the internet.  But when writing non object oriented functions that don&amp;rsquo;t use &lt;code&gt;this&lt;/code&gt; like our example above, it is mostly not relevant.  In this case though, the cleaner syntax that arrow functions provide allow us to write a clear and clean higher order function to solve our use case.  With arrow functions, our example from above now looks like this.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; { commentList } from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;./comments&amp;#39;&lt;/span&gt;;

&lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; getCommentFromUser &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; (comments) =&amp;gt; (userId) =&amp;gt; ({
    user&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; userId,
    comments&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; comments.filter( (comment) =&amp;gt; comment.user &lt;span style=&#34;color:#ff79c6&#34;&gt;===&lt;/span&gt; userId),
})

&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; userIds &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; [&lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;, &lt;span style=&#34;color:#bd93f9&#34;&gt;4&lt;/span&gt;, &lt;span style=&#34;color:#bd93f9&#34;&gt;5&lt;/span&gt;],
    userComments &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; userIds.map(getCommentFromUser(commentList));

&lt;span style=&#34;color:#6272a4&#34;&gt;//do stuff with comments
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I like to call the &lt;code&gt;() =&amp;gt; () =&amp;gt;&lt;/code&gt; pattern a &amp;ldquo;double function&amp;rdquo;, and have found it popping up all over the code I write since I began using ES6, especially when I&amp;rsquo;m using &lt;code&gt;map&lt;/code&gt;, &lt;code&gt;filter&lt;/code&gt;, and &lt;code&gt;reduce&lt;/code&gt;.  Array transformations using those functions often require contextual information beyond the contents of the array.  A naive approach to this would involve having the function reference variables in the outer scope directly, like we did with commentList above.  More commonly that happens when a user inlines a function inside of a &lt;code&gt;map&lt;/code&gt; call and references variables in the parent scope.  I&amp;rsquo;ve found that it is much clearer and less error prone to use a higher order function that takes only the variables that are needed for the transformation in, and returns a new function that can be used for the transformation.  This reduces the number of things that can effect the output of the function, allows for greater configurability without directly changing the transformation logic, and makes it clear to readers what values are expected to be used in the function.  Double functions make this easy, and they&amp;rsquo;ve easily been one of my favorite new code patterns with ES6.&lt;/p&gt;
&lt;h3 id=&#34;more-resources&#34;&gt;More Resources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;If you&amp;rsquo;re interested in higher order functions and JavaScript, I know of no better reference than &lt;a href=&#34;https://leanpub.com/javascriptallongesix&#34;&gt;JavaScript Allongé&lt;/a&gt;.  It&amp;rsquo;s a fantastic deep dive into the JavaScript language with a functional flavor, building understanding from the bottom up and providing many ideas for code recipes along the way.  And it&amp;rsquo;s recently been rewritten to reflect the changes to the language that ES6 brought.&lt;/li&gt;
&lt;li&gt;Here&amp;rsquo;s a nice &lt;a href=&#34;http://www.2ality.com/2012/04/arrow-functions.html&#34;&gt;deep dive on arrow functions at 2ality&lt;/a&gt; by Axel Rauschmayer.  If you haven&amp;rsquo;t seen his blog, it&amp;rsquo;s a fantastic reference on ES6 and JavaScript in general&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Productive JavaScript Development</title>
      <link>https://benmccormick.org/2015/11/25/094346.html</link>
      <pubDate>Wed, 25 Nov 2015 10:43:46 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2015/11/25/094346.html</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve been thinking a lot lately about how we as a JavaScript community can enable more productive JavaScript development.  Most of the major JavaScript libraries were created or popularized to further a theory of how we can be more productive.  jQuery emerged when the biggest productivity challenge for web developers was the incompatible implementations of JavaScript and browser APIs in different browsers.  It largely solved that problem.  Since then, Backbone advocates have pushed for greater productivity through libraries with minimal abstraction where users can understand the source code, Ember has created an ecosystem around the idea that &amp;ldquo;shared solutions&amp;rdquo; lead to greater productivity, Angular aimed to make developers (and designers) more productive by adding more power to concepts that were already familiar to them, and React is trying to improve productivity by simplifying the programming model around interfaces.  Meanwhile, tangential to the big frameworks, there has been work to enable more productive development through transpile-to-JavaScript languages (CoffeeScript, TypeScript, Elm, ClojureScript etc), replacing JavaScript on the web period (Dart, WebAssembly, ASM.js), and improving the core JavaScript language while allowing developers to use new features early (ES6 and beyond, as well as Babel).  There&amp;rsquo;s also work to improve tooling around JavaScript with projects like &lt;a href=&#34;http://ternjs.net/&#34;&gt;Tern.js&lt;/a&gt;, &lt;a href=&#34;https://github.com/gaearon/react-hot-loader&#34;&gt;Time Machine/React Hot Loader&lt;/a&gt;, and continued improvements to Chrome and Firefox developer tools (along with Framework specific developer tools). So there&amp;rsquo;s no shortage of work being done in this area.  But let&amp;rsquo;s pull out for a moment.  What are the big picture things that affect productivity?&lt;/p&gt;
&lt;p&gt;Most of the time productivity tools are focused on one of 6 areas.  They make it easier to learn concepts,  easier to write code, easier to read code, easier to architect applications, easier to maintain applications, or easier to debug applications. Here are some examples of each&lt;/p&gt;
&lt;h4 id=&#34;easy-to-learn&#34;&gt;Easy To Learn&lt;/h4&gt;
&lt;p&gt;Angular and Backbone both try to improve programmer productivity by being easy to learn, each in different ways.  Angular puts much of its view logic inside HTML, a medium that many server-side developers and designers are already familiar with.  Therefore it&amp;rsquo;s a reduced learning curve than something like React, where the UI tends to be more spread across files and is mixed with JavaScript logic &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.  Angular also provides extensive documentation, which helps programmers come up to speed faster.&lt;/p&gt;
&lt;p&gt;Backbone on the other hand, attempts to be easy to learn in two ways.  First, there just isn&amp;rsquo;t that much to learn.  Backbone is a small library with only 6 core concepts (Models, Collections, Views, Events, and Router) each of which should be familiar to developers coming to it from other UI focused frameworks.  That simplicity reduces the load on new users.  At the same time Backbone strives to have libary source code that is both short and readable.  It&amp;rsquo;s quite possible to read the code for the whole library in under an hour, and the core concepts are obvious when looking through the code.&lt;/p&gt;
&lt;h4 id=&#34;easy-to-write&#34;&gt;Easy to Write&lt;/h4&gt;
&lt;p&gt;Ember.js aims to make it easy to write application code in at least 2 ways.  First it provides &lt;a href=&#34;http://www.ember-cli.com/&#34;&gt;tooling&lt;/a&gt; to help generate the boilerplate necessary for an ember application.  You can give ember-cli a model name and it will generate the file for that model in the correct place.  In addition Ember abstracts away many of the connections between classes so that you can load the correct files simply using naming conventions, resulting in less code.&lt;/p&gt;
&lt;p&gt;The recent updates to the JavaScript language are about much more than just making it easier to write JavaScript, but several of the features are focused on providing cleaner syntax for common idioms.  Arrow functions in particular allow for maintaining the outer scope of a function in a clean way, when previously it required jumping through hoops that were easy to mess up.&lt;/p&gt;
&lt;p&gt;Redux and React Hot loader are an attempt to develop a programming idiom that allows for drastically reduced latency between making a change and seeing a result.  A React app using redux and a hot loader can be updated instantly without losing state and cycle backwards and forward through state updates.  Lower latency between writing code and seeing the results makes it much easier to iterate quickly towards good code.&lt;/p&gt;
&lt;h4 id=&#34;easy-to-read&#34;&gt;Easy to Read&lt;/h4&gt;
&lt;p&gt;One of the biggest gains provided by React is an increase in the readability of code by combining all of the elements of a component (JavaScript, HTML and in some cases CSS) into a single file where the component can be read as a coherent whole without flipping through code.&lt;/p&gt;
&lt;p&gt;CoffeeScript is an attempt to strip out the unnecessary syntax bloat of JavaScript and focus on the pure logic.  Whether it succeeds is a totally different question, but it&amp;rsquo;s a great example of attempting to satisfy this side of the productivity problem by reducing the distractions in code.&lt;/p&gt;
&lt;p&gt;Type annotation tools like TypeScript and Flow also aim to increase code readability, but not by clearing out bloat (annotations can actually make the code feel more crowded and less readable at first).  Instead they add additional information to the code, making the structure and expectations of the code more apparent to a reader.&lt;/p&gt;
&lt;h4 id=&#34;easy-to-architect&#34;&gt;Easy to Architect&lt;/h4&gt;
&lt;p&gt;Ember really shines when it comes to making it easy to architect apps.  By providing clear guidance on how to structure apps, it can increase productivity by reducing bike-shedding.  In Ember every state of the UI is tied to a URL and each route is tied to controllers that display components.  Communication between components happens with actions and data is managed by Ember Data.  Thats a reasonable architecture thats general enough to work for most large web applications (Embers target).&lt;/p&gt;
&lt;p&gt;Unfortunately examples of innovation in this area are much more sparse than the others here, probably because it&amp;rsquo;s hard to demonstrate in a todo app.  There&amp;rsquo;s been a recent spate of interest in application architecture from all of the Flux implementations that have popped up for React apps.  I&amp;rsquo;ve also seen interest in the architecture model of &lt;a href=&#34;http://elm-lang.org/&#34;&gt;Elm&lt;/a&gt;.  But most of the major MVC frameworks have much less community agreement on architecture than they do on smaller scoped issues.&lt;/p&gt;
&lt;h4 id=&#34;easy-to-maintain&#34;&gt;Easy to Maintain&lt;/h4&gt;
&lt;p&gt;There are a lot of technologies around JavaScript that promise to make your code more maintainable.  Module loaders like requireJS, browserify and webpack, linters like ESLint and JSHint, type checkers like TypeScript and Flow, and test runners like Mocha and Karma all provide tooling around maintainability.&lt;/p&gt;
&lt;p&gt;At the framework Backbone addresses the idea of maintainability by keeping small and flexible enough to remain usable as requirements change.  React deals with it by simplifying the programming model enough that its easier for new developers to see whats going on.  And Ember deals with it by maintaining a disciplined process for continually improving the framework to &amp;ldquo;keep up with the web&amp;rdquo; without leaving developers behind.&lt;/p&gt;
&lt;h4 id=&#34;easy-to-debug&#34;&gt;Easy To Debug&lt;/h4&gt;
&lt;p&gt;In recent years a lot of work has gone into improving developer tools for debugging JavaScript. This has happened at 3 levels.  First browser vendors, especially Google and Mozilla,  have made a huge investment in improving the developer tools that ship with browsers.  It&amp;rsquo;s now possible to identify many errors quickly that would have been mere guesswork before.  Secondly, frameworks have worked on building their own developer tools.  React and Ember both have incredibly powerful debugging tools with first class support from the framework team.  Marionette (a framework for Backbone apps) has a similarly rich debugging tool, and Angular also has tools for debugging.  Finally, linters and transpilers are also helping to catch some classes of errors at compile time rather than waiting to discover them at run-time.&lt;/p&gt;
&lt;p&gt;Other than tools though, Frameworks can have some features that make them easier or harder to debug.  React and Angular both make a big deal of being easy to write tests for.  In Angular this is true because of their dependency injection system.  In React this works out because React components are basically pure functions that take state and properties and return DOM.  Pure functions are easy to test, especially compared to traditional UIs that are tied to the global mutable DOM. Backbone also contributes to easier debugging by presenting a relatively straightforward and readable source that developers can trace through without becoming baffled by &amp;ldquo;library mystery meat&amp;rdquo;.&lt;/p&gt;
&lt;h3 id=&#34;choices-choices&#34;&gt;Choices, Choices&lt;/h3&gt;
&lt;p&gt;When picking a toolset in JavaScript it&amp;rsquo;s helpful to think about all 6 of the above areas.  Any library or framework that has gotten past the minimum threshold of solving a problem will claim to help you in at least one of these areas.  But a useful comparison will run across all six.  What do you think are the best tools for a truly productive workflow in the JavaScript community today?&lt;/p&gt;
&lt;div class=&#34;footnotes&#34;&gt;
&lt;ol&gt;
    &lt;li class=&#34;footnote&#34; id=&#34;fn:1&#34;&gt;
        &lt;p&gt;
        Not saying that this is the best way to make things easy to learn, just that it is a goal.
        &lt;/p&gt;
        &lt;a href=&#34;#fnref:1&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>ES5, ES6, ES2016, ES.Next: What&#39;s going on with JavaScript versioning?</title>
      <link>https://benmccormick.org/2015/09/13/221134.html</link>
      <pubDate>Sun, 13 Sep 2015 23:11:34 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2015/09/14/221134.html</guid>
      <description>&lt;p&gt;JavaScript has a strange naming history. For its initial release in 1995 as part of Netscape Navigator, Netscape labeled their new language LiveScript, before renaming it to JavaScript a year later, hoping to capitalize on Java&amp;rsquo;s popularity at the time (&lt;a href=&#34;http://www.coderanch.com/t/456377/a/401/javascript-java.jpg&#34;&gt;JavaScript has no actual relationship to Java&lt;/a&gt;). In 1996 Netscape submitted JavaScript to &lt;a href=&#34;http://www.ecma-international.org/&#34;&gt;ECMA International&lt;/a&gt; for standardization.  This eventually resulted in a new language standard, labeled ECMAScript.  All major JavaScript implementations since have actually been implementations of the ECMAScript standard, but the term JavaScript has stuck for historical and marketing reasons &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.  In the real world ECMAScript is usually used to refer to the standard while JavaScript is used when talking about the language in practice.&lt;/p&gt;
&lt;p&gt;This has mostly been trivia for JavaScript developers, because ECMAScript didn&amp;rsquo;t change much for the first 15 years of its existence, and real world implementations often differed significantly from the standard.  After the initial version of ECMAScript, work on the language continued and two more versions were quickly published.  But after ECMASCript 3 came out in 1999, there were no changes made to the official standard for a decade.  Instead various browser vendors made their own custom extensions to the language, and web developers were left to try and support multiple APIs.  Even after ECMAScript 5 was published in 2009, it took several years for wide browser support of the new spec, and most developers continued to write code in ECMAScript 3 style, without necessarily being aware of the standard.&lt;/p&gt;
&lt;p&gt;Around 2012 things started to change.  There was more of a push to stop supporting old Internet Explorer versions, and writing code in ECMAScript 5 (ES5) style became much more feasible.  At the same time work was underway on a new ECMAScript standard, at which point it became much more common to start referring to JavaScript implementations in terms of their support for different ECMAScript standards.  The new standard was originally named ES.Harmony, before eventually being referred to as ECMAScript 6th Edition (ES6). In 2015 TC39, the committee responsible for drafting the ECMAScript specifications, made the decision to move to a yearly model for defining new standards, where new features would be added as they were approved, rather than drafting complete planned out specs that would only be finalized when all features were ready.  As a result ECMAScript 6th edition was renamed ECMAScript 2015 (ES2015) before it was published in June.&lt;/p&gt;
&lt;p&gt;Currently there are several proposals for new features or syntax to be added to JavaScript.  These include &lt;a href=&#34;https://github.com/wycats/javascript-decorators&#34;&gt;decorators&lt;/a&gt;, &lt;a href=&#34;https://github.com/lukehoban/ecmascript-asyncawait&#34;&gt;async-await&lt;/a&gt;, and &lt;a href=&#34;https://gist.github.com/jeffmo/054df782c05639da2adb&#34;&gt;static class properties&lt;/a&gt;.  These are often refered to as ES7, ES2016, or ES.Next features, but should realistically be called proposals or possibilities, since the ECMAScript 2016 specification hasn&amp;rsquo;t been written yet, and might include all or none of those features.  TC39 divides proposals into 4 stages.  You can see the current state of various proposals on &lt;a href=&#34;https://github.com/tc39/proposals&#34;&gt;the TC39 Github repo&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So where does that leave us in terms of terminology?  The following list might be helpful:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ECMAScript&lt;/strong&gt;: A language standardized by ECMA International and overseen by the TC39 committee.  This term is usually used to refer to the standard itself.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;JavaScript&lt;/strong&gt;: The commonly used name for implementations of the ECMAScript standard.  This term isn&amp;rsquo;t tied to a particular version of the ECMAScript standard, and may be used to refer to implementations that implement all or part of any particular ECMASCript edition.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ECMAScript 5 (ES5)&lt;/strong&gt;: The 5th edition of ECMAScript, standardized in 2009.  This standard has been implemented fairly completely in all modern browsers&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ECMAScript 6 (ES6)/ ECMAScript 2015 (ES2015)&lt;/strong&gt;: The 6th edition of ECMAScript, standardized in 2015.  This standard has been partially implemented in most modern browsers.  To see the state of implementation by different browsers and tools, check out &lt;a href=&#34;http://kangax.github.io/compat-table/es6/&#34;&gt;these compatibility tables&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ECMAScript 2016&lt;/strong&gt;: The expected 7th edition of ECMAScript. This is scheduled to be released next summer.  The details of what the spec will contain have not been finalized yet&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ECMAScript Proposals&lt;/strong&gt;: Proposed features or syntax that are being considered for future versions of the ECMAScript standard.  These move through a process of five stages: Strawman, Proposal, Draft, Candidate and Finished.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Going forward in this blog, I&amp;rsquo;ll be referring to the recent ECMAScript version as ES6 (since that is how it is best known by most developers), next years spec as ES2016 (since that will be what it is called the whole way through its standardization process, unlike ES6/ES2015) and future language ideas that are not yet part of a draft or finalized spec as ECMAScript proposals or JavaScript proposals.  I&amp;rsquo;ll do my best to point back to this post in any cases that might be confusing.&lt;/p&gt;
&lt;h3 id=&#34;more-resources&#34;&gt;More Resources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;If you&amp;rsquo;re wondering about the best way to keep up with JavaScript language changes, check out the resources &lt;a href=&#34;https://benmccormick.org/2017/07/10/how-to-follow-the-javascript-roadmap/&#34;&gt;in this post&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;TC39 has a &lt;a href=&#34;https://github.com/tc39/ecma262&#34;&gt;github repo&lt;/a&gt; tracking all of their current open proposals.&lt;/li&gt;
&lt;li&gt;If you aren&amp;rsquo;t familiar with ES6 yet, Babel has a &lt;a href=&#34;https://babeljs.io/docs/learn-es2015/&#34;&gt;great rundown of its features&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;If you want to go deeper with ES6 I&amp;rsquo;ve heard great things  about 2 books on the subject: &lt;a href=&#34;http://exploringjs.com/&#34;&gt;Exploring ES6&lt;/a&gt; by Axel Rauschmayer and &lt;a href=&#34;https://leanpub.com/understandinges6&#34;&gt;Understanding ECMAScript 6&lt;/a&gt; by Nicholas Zakas&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;.  Axel&amp;rsquo;s blog &lt;a href=&#34;http://www.2ality.com/&#34;&gt;2ality&lt;/a&gt; is also a great ES6 resource.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;footnotes&#34;&gt;
&lt;ol&gt;
    &lt;li class=&#34;footnote&#34; id=&#34;fn:1&#34;&gt;
        &lt;p&gt;
        And obviously because ECMAScript is an awful language name
        &lt;/p&gt;
        &lt;a href=&#34;#fnref:1&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li class=&#34;footnote&#34; id=&#34;fn:2&#34;&gt;
        &lt;p&gt;
        Note that I have not read either of these books yet, though I have read plenty of other content from both authors and consider them experts on the JavaScript language. So take that recommendation with an appropriate grain of salt.
        &lt;/p&gt;
        &lt;a href=&#34;#fnref:2&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Lessons Backbone Developers Can Learn From React</title>
      <link>https://benmccormick.org/2015/09/09/061943.html</link>
      <pubDate>Wed, 09 Sep 2015 07:19:43 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2015/09/09/061943.html</guid>
      <description>&lt;p&gt;Since I started programming professionally, I&amp;rsquo;ve always kept an informal list of technologies I want to check out.  Things that I thought would be useful for my career, would expose me to new ideas, or just looked plain cool.  I spent a chunk of my Labor Day weekend working through that list a bit by learning more about &lt;a href=&#34;http://facebook.github.io/react/&#34;&gt;React&lt;/a&gt;, the JavaScript View library from Facebook. React is a fascinating piece of technology, and a strong ecosystem of tools and libraries is growing up around it.  For developers starting brand new front-end projects in 2015, it ranks as one of the 2 main libraries I&amp;rsquo;d suggest looking into as a base, along with &lt;a href=&#34;http://emberjs.com/&#34;&gt;Ember&lt;/a&gt;.  Most developers though are not starting brand new projects.  We&amp;rsquo;re maintaining existing code, or starting a new project while trying to reuse components of an old one.  Fortunately, React is about ideas as much as it is technology.  For this piece, I&amp;rsquo;m going to go through the big ideas of React and look at 3 of them that developers working on other frameworks (and &lt;a href=&#34;http://backbonejs.org/&#34;&gt;Backbone&lt;/a&gt; in particular) can learn from.  There&amp;rsquo;s a lot more to React and its community than just these 3 ideas, so I&amp;rsquo;ll also include some extra resources at the bottom for those interested in learning more about it.&lt;/p&gt;
&lt;h3 id=&#34;idea-1-interfaces-should-be-a-tree-of-composable-components&#34;&gt;Idea 1: Interfaces should be a tree of composable components&lt;/h3&gt;
&lt;p&gt;React interfaces are constructed by combining many small &amp;ldquo;components&amp;rdquo;, each of which can be created by combining other smaller components.  In the end a normal React interface will resemble a tree, with a top level component that encompasses the whole app and many smaller components nested inside of it.  It&amp;rsquo;s a model that should be familiar; the browser DOM works the same way.&lt;/p&gt;
&lt;p&gt;Building interfaces this way lets you reuse more code and also makes code easier to reason about.  Because you&amp;rsquo;re composing your interfaces rather than using inheritance or monolithic page objects to build your pages, you can write common code for items like buttons, date-pickers and lists once and then re-use them all over place, even creating larger components like a dialog box out of smaller components like buttons, inputs and an overlay.  And since components are small and focused, it&amp;rsquo;s much easier to dive into them and understand what is going on.  Since react components are built to work in this standardized ways, you can be comfortable knowing that no other code is going to be changing the area of the UI controlled by that component.&lt;/p&gt;
&lt;p&gt;Backbone doesn&amp;rsquo;t enforce a specific way to organize your UI code.  You can create a single Backbone View for a whole page, have different non-nested views control different portions of a page, or use a nested scheme.  For simple sites or apps, each of these can make sense.  You probably don&amp;rsquo;t need a nested component tree for a simple content page with one or two pieces of interactive behavior.  But for large rich apps, small composable Views (or other building blocks) can provide much more flexibility, allowing you to mix and match pieces of your application to build diverse pages without becoming overwhelmed with code.&lt;/p&gt;
&lt;p&gt;Building this sort of tree system in Backbone is one of the main selling points of &lt;a href=&#34;http://marionettejs.com/&#34;&gt;Marionette&lt;/a&gt;, the most popular of several libraries that add conventions on top of Backbone&amp;rsquo;s structure.  Marionette provides collection Views and layout Views that &lt;a href=&#34;http://benmccormick.org/2014/12/22/building-complex-layouts-with-marionette-js/&#34;&gt;let you build rich View trees&lt;/a&gt; that are very similar in structure to a React app, while maintaining compatibility with Backbone&amp;rsquo;s code and the Backbone communities conventions.  It&amp;rsquo;s also possible to compose an applications interface with a mix of Backbone and other &amp;ldquo;components&amp;rdquo;; for instance using &lt;a href=&#34;http://webcomponents.org/&#34;&gt;web components&lt;/a&gt;, React Components, or even jQuery UI widgets to represent individual pieces in an application and then tying together their layout using Backbone Views.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s not to say there are no problems with implementing this style in Backbone though.  For one thing, when nesting one Backbone view inside of another, Backbone does not provide strong encapsulation of child views.  Because Backbone Views act on HTML directly, when a parent view listens to an event or modifies HTML directly, it is possible for the view to listen to events on elements controlled by a child view and even modify those elements directly.  That can create confusing side effects, since in a deeply nested view tree it means an event could lead to code being triggered in one of many different Views, and the state of that piece of DOM could be affected by many different areas of code at once.  In Backbone these problems must mostly be solved with programmer discipline, a weight that adds to the difficulty of deeply nested UIs, but doesn&amp;rsquo;t prevent them.&lt;/p&gt;
&lt;h3 id=&#34;idea-2-modern-javascript-leads-to-cleaner-code&#34;&gt;Idea 2: Modern JavaScript leads to cleaner code&lt;/h3&gt;
&lt;p&gt;Using modern JavaScript is less a core idea of React, and more a value of its community.  When researching React, almost every example of React code I found was written using &lt;a href=&#34;https://babeljs.io/docs/learn-es2015/&#34;&gt;ES6 style JavaScript code&lt;/a&gt; and a modern module system (commonJS or ES6 modules using either &lt;a href=&#34;https://webpack.github.io/&#34;&gt;webpack&lt;/a&gt; or &lt;a href=&#34;http://browserify.org/&#34;&gt;browserify&lt;/a&gt;).  Many React developers are even pushing the boundaries of todays browsers and standards and experimenting with how their code could be improved by proposed ES7 features.  I rarely see Backbone code examples using these styles.  They&amp;rsquo;re usually in ES5 style or &lt;a href=&#34;http://coffeescript.org/&#34;&gt;Coffeescript&lt;/a&gt; and use AMD modules or global namespaces to structure code.  Some of this is a natural function of the hype cycle: most Backbone code examples were written 3-4 years ago when it was the hot new JavaScript framework, while most React examples are written now.  But the net result is that most people who use Backbone today aren&amp;rsquo;t being exposed to these new styles and tools.  Since things like JavaScript APIs and module loaders can be chosen separate from what framework you choose &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;, this is an opportunity to take advantage of innovation from other places without giving up an investment in Backbone.&lt;/p&gt;
&lt;p&gt;Take the following code examples for instance.  This is the same View written in 3 styles: ES5 with namespaces, ES6 and ES7.  Compare the readability and usability in each case.  The example is just a simple view that takes a template, logs a message when it is created and shows a different modal when 2 different buttons are clicked, with a callback function after the modal is closed.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;//ES5 with namespaces
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;(&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(App, Backbone, Modal, _) {

    App.ExampleView &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; Backbone.View.extend({

        template&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; App.templates[&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;exampleview&amp;#39;&lt;/span&gt;],

        events&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;() {
            &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;click .example-button&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;showSuccess&amp;#39;&lt;/span&gt;,
            &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;click .example-button2&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;showError&amp;#39;&lt;/span&gt;,
        },

        constructor&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;() {
            Backbone.View.apply(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;, [].slice.call(arguments));
            console.log(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Created a Example View&amp;#39;&lt;/span&gt;);
        },

        render&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;() {
            &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.$el.html(_.template(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.template)(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.model.attributes));
        },

        showSuccess&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;() {
            &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.showModal(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;You did it&amp;#39;&lt;/span&gt;);
        },

        showError&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;() {
            &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.showModal(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;You failed&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Error&amp;#39;&lt;/span&gt;);
        },

        showModal&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(message, title) {
            &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#ff79c6&#34;&gt;typeof&lt;/span&gt; title &lt;span style=&#34;color:#ff79c6&#34;&gt;===&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;undefined&amp;#39;&lt;/span&gt;) {
                title &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Alert&amp;#39;&lt;/span&gt;;
            }
            Modal.show(message, title, &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.onModalClose.bind(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;));
        },

        onModalClose&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;() {
            console.log(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;re-rendering after modal closes to capture any changes&amp;#39;&lt;/span&gt;);
            &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.render();
        },
    })

})(App &lt;span style=&#34;color:#ff79c6&#34;&gt;||&lt;/span&gt; {}, Backbone, Modal, _);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Obviously the scenario is a bit contrived here (we&amp;rsquo;d want to generalize any logging in the constructor in real life, and we would listen for model changes to re-render rather than just blindly doing it in a callback).  But notice how many confusing things are going on that are completely incidental to what the code is doing.  A JavaScript beginner would have a lot to work through in this example.  Why is the whole file wrapped in a function?  Where do Backbone and Modal come from?  What&amp;rsquo;s going on with &lt;code&gt;Backbone.View.apply(this, [].slice.call(arguments));&lt;/code&gt;?  That&amp;rsquo;s even aside from the incidental complexity of having to know what order your files are loaded in when using this particular module style.  We can do so much better.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;//ES6
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; {View} from Backbone;
&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;*&lt;/span&gt; as Modal from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;utils/modal&amp;#39;&lt;/span&gt;;
&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; {template} from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;lodash&amp;#39;&lt;/span&gt;;
&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;*&lt;/span&gt; as ExampleViewTemplate from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;templates/exampleview&amp;#39;&lt;/span&gt;;

&lt;span style=&#34;color:#ff79c6&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;const&lt;/span&gt; ExampleView &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; View.extend({

    template&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; ExampleViewTemplate,

    events() {
        &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;click .example-button&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;showSuccess&amp;#39;&lt;/span&gt;,
        &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;click .example-button2&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;showError&amp;#39;&lt;/span&gt;,
    },

    constructor(...args) {
        View.apply(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;, args));
        console.log(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Created a Example View&amp;#39;&lt;/span&gt;);
    },

    render() {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.$el.html(template(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.template)(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.model.attributes));
    },

    showSuccess() {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.showModal(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;You did it&amp;#39;&lt;/span&gt;);
    },

    showError() {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.showModal(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;You failed&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Error&amp;#39;&lt;/span&gt;);
    },

    showModal(message, title&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Alert&amp;#39;&lt;/span&gt;) {
        Modal.show(message, title, () =&amp;gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.onModalClose());
    },

    onModalClose() {
        console.log(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;re-rendering after modal closes to capture any changes&amp;#39;&lt;/span&gt;);
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.render();
    },
});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;ES6 allows us to clean up our original example a lot!  We&amp;rsquo;re able to ditch the wrapping function, and instead pull our dependencies directly at the top of the file, with clear pointers to module paths so that new developers can easily go find the code we&amp;rsquo;re referencing.  At a smaller level, we&amp;rsquo;ve cleaned up many of the annoyances from the original code.  We no longer have to slice arguments; instead we can use the rest operator to collect all of the arguments as an array and pass them to the constructor directly.  Similarly, we don&amp;rsquo;t need to explicitly check for undefined anymore in showModal since we can display default arguments.  Finally, we can get rid of some function boilerplate, removing the function keyword completely for object methods and changing the &lt;code&gt;bind(this)&lt;/code&gt; from onModalClose to use an ES6 lambda function.  All of this is helpful, and represents the best of what is stable for production at the moment.  But if we want to look ahead to the current proposed ES7 additions, we&amp;rsquo;ll be able to clean this code up even more.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;//ES7
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; {View} from Backbone;
&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;*&lt;/span&gt; as Modal from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;utils/modal&amp;#39;&lt;/span&gt;;
&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; {template} from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;lodash&amp;#39;&lt;/span&gt;;
&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;*&lt;/span&gt; as ExampleViewTemplate from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;templates/exampleview&amp;#39;&lt;/span&gt;;

&lt;span style=&#34;color:#ff79c6&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; ExampleView &lt;span style=&#34;color:#ff79c6&#34;&gt;extends&lt;/span&gt; View {

    template &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; ExampleViewTemplate;

    constructor(...args) {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;super&lt;/span&gt;(args);
        console.log(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Created a Example View&amp;#39;&lt;/span&gt;);
    }

    render() {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.$el.html(template(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.template)(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.model.attributes));
    }

    @on(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;click .example-button&amp;#39;&lt;/span&gt;)
    showSuccess() {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.showModal(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;You did it&amp;#39;&lt;/span&gt;);
    }

    @on(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;click .example-button2&amp;#39;&lt;/span&gt;)
    showError() {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.showModal(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;You failed&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Error&amp;#39;&lt;/span&gt;);
    }

    showModal(message, title&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Alert&amp;#39;&lt;/span&gt;) {
        Modal.show(message, title, &lt;span style=&#34;color:#ff79c6&#34;&gt;::&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.onModalClose);
    }

    onModalClose() {
        console.log(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;re-rendering after modal closes to capture any changes&amp;#39;&lt;/span&gt;);
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.render();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;ES7 allows us to clean up more boilerplate using classes &lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;, static properties, and &lt;code&gt;::&lt;/code&gt; as a special shorthand for function binding.  But it also allows us to start actually improving the interface of Backbone itself.  The example above uses decorators to define extra behaviors that wrap the View&amp;rsquo;s methods. In this case decorators &lt;a href=&#34;http://benmccormick.org/2015/07/06/backbone-and-es6-classes-revisited/&#34;&gt;allow us to contextualize the events to function mapping&lt;/a&gt; for our View, improving on the default events hash that Backbone provides.  There are many examples of similar convenient conventions that are being experimented with in the React community. Backbone developers can learn a lot here by looking through React code.  Since React components are syntactically similar to Backbone Views (even though the underlying model is quite different), it&amp;rsquo;s easy to learn a lot of new JavaScript techniques that can be used in Backbone in the process.&lt;/p&gt;
&lt;h3 id=&#34;idea-3-dont-use-dom-as-a-source-of-state&#34;&gt;Idea 3: Don&amp;rsquo;t use DOM as a source of state&lt;/h3&gt;
&lt;p&gt;The final big idea that Backbone developers can learn from React is its insistence on not using the DOM as a source of state.  React encourages a programming model where in theory, any component can be re-rendered at any time based on a change in data.  That means that any UI state must be captured in code and not in the UI.  This is another approach that requires programmer discipline in Backbone.  It means that instead of just typing out &lt;code&gt;this.$(&#39;.main-content&#39;).addClass(&#39;highlighted&#39;)&lt;/code&gt;, you&amp;rsquo;ll want to set an &lt;code&gt;contentIsHighlighted&lt;/code&gt; variable somewhere and then either re-render your view or do a structured update based on your state.  That way, instead of having to read the DOM later to know the state of your application it is all copied in code.  This leads to better testability, more predictable code and fewer edge cases when the structure of your HTML changes.&lt;/p&gt;
&lt;p&gt;This idea was historically the primary benefit for Backbone apps over pure jQuery applications.  But the truth is that while Backbone does a good job of pulling application data into code with models and collections, it makes it very tempting to encode UI state info in the DOM by exposing jQuery helpers and not providing a canonical way to store view state.  Still, a little discipline goes a long way.  By using a separate Backbone Model as a view-model or just storing your state as properties on the view object itself, you can pull your state out of the DOM and make it much easier to inspect and reason about when you&amp;rsquo;re debugging your code or trying to refactor.&lt;/p&gt;
&lt;p&gt;You probably can&amp;rsquo;t take this idea to the full extent that React takes it using Backbone.  The extreme end of the React philosophy is to use React components as stateless functions that simply take application data and ui state as arguments and return an HTML representation of the UI.  This means that React interfaces can be re-rendered completely after any change without losing information.  React supports this and makes it performant by using a &amp;ldquo;virtual DOM&amp;rdquo; to generate the new HTML that would result from a data or state change, compare it to the existing HTML, and then only make the changes that are required in the actual DOM &lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;.  That works well in React since it has a clear concept of what is controlled by each component.  As previously noted, Backbone does not strongly encapsulate its Views, which complicates doing the type of virtual DOM analysis that React manages.  So it&amp;rsquo;s more practical to focus on pulling state out of Views and managing re-renders based on Backbone&amp;rsquo;s event system (the idiomatic Backbone approach).  If you want to pursue the UI as pure functional programming paradigm, you&amp;rsquo;d probably do better moving off Backbone to a system designed for that like React, &lt;a href=&#34;http://cycle.js.org/&#34;&gt;cycle.js&lt;/a&gt;, &lt;a href=&#34;https://github.com/omcljs/om&#34;&gt;Om&lt;/a&gt;, or &lt;a href=&#34;https://github.com/Reactive-Extensions/RxJS&#34;&gt;rxjs&lt;/a&gt;.  But even if you can&amp;rsquo;t go all in on functional UI programming in your current code base, understanding the problems inherent with using DOM to manage state will help you write better Backbone apps.&lt;/p&gt;
&lt;h3 id=&#34;react-resources-round-up&#34;&gt;React Resources Round-up&lt;/h3&gt;
&lt;p&gt;If you&amp;rsquo;re interested in learning more about React, many others have put together better resources than I&amp;rsquo;m capable of.  Here&amp;rsquo;s a quick roundup of some of the resources I&amp;rsquo;ve found helpful.&lt;/p&gt;
&lt;h4 id=&#34;intro&#34;&gt;Intro&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;If you want to get a big picture view of what React is about, I&amp;rsquo;d recommend starting with this &lt;a href=&#34;https://www.youtube.com/watch?v=x7cQ3mrcKaY&#34;&gt;2013 conference video&lt;/a&gt; where a member of the React team, addresses some of the criticisms that React received early on and lays out the ideas behind the library.  Some of the details have changed since, but the big picture view remains.&lt;/li&gt;
&lt;li&gt;The React documentation is also exceptionally well-written and accessible.  This blurb on &lt;a href=&#34;http://facebook.github.io/react/docs/thinking-in-react.html&#34;&gt;thinking in react&lt;/a&gt; is a good place to start.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;talks&#34;&gt;Talks&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;If you want to see some of the nice potential side effects that React can provide &lt;a href=&#34;https://www.youtube.com/watch?v=xsSnOQynTHs&#34;&gt;this talk&lt;/a&gt; by Dan Abramov, the creator of Redux, shows how easy it is to create developer tools that significantly improve a developers feedback loop and user experience while writing code.&lt;/li&gt;
&lt;li&gt;The &lt;a href=&#34;https://www.youtube.com/watch?v=PAA9O4E1IM4&#34;&gt;keynote from React Europe&lt;/a&gt; gives a good feel for the current state of the ecosystem around React.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;articles&#34;&gt;Articles&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://rauchg.com/2015/pure-ui/&#34;&gt;Pure UI&lt;/a&gt; by Guillermo Rauch is the best explanation I&amp;rsquo;ve read of the benefits of the UI model that React encourages, though it is not specifically about React.&lt;/li&gt;
&lt;li&gt;One of the biggest instinctive objections many developers have when they first see React code is the mixing of JavaScript and the HTML syntax of JSX inside a single file.  &lt;a href=&#34;https://medium.com/javascript-scene/jsx-looks-like-an-abomination-1c1ec351a918&#34;&gt;Eric Elliot has a nice post on medium&lt;/a&gt; examining those objections and explaining why JSX makes sense.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;projects&#34;&gt;Projects&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://facebook.github.io/flux/&#34;&gt;Flux&lt;/a&gt; is one of the 2 main data management frameworks that Facebook and the React team recommend for use with React.  The second newer one, &lt;a href=&#34;https://facebook.github.io/relay/&#34;&gt;Relay&lt;/a&gt; is a bit more crazy advanced and requires a very specific type of backend API to implement.  If you&amp;rsquo;re interested in Flux, also make sure to check out &lt;a href=&#34;https://github.com/rackt/redux&#34;&gt;Redux&lt;/a&gt;, an opinionated flux implementation focused pure functional programming concepts.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/rackt/react-router&#34;&gt;React Router&lt;/a&gt; is a router for React applications based on Ember&amp;rsquo;s router.  It provides a nice declarative model for defining routes based on JSX, the JS language extension that Facebook created along with React&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://babeljs.io/&#34;&gt;Babel&lt;/a&gt; isn&amp;rsquo;t a react specific technology, but its important to understand it if you want to digest most of the React examples out there, or build a React app yourself, since it is now recommended as the tool for writing React code in an idiomatic style.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;footnotes&#34;&gt;
&lt;ol&gt;
    &lt;li class=&#34;footnote&#34; id=&#34;fn:1&#34;&gt;
        &lt;p&gt;
        Well at this point many frameworks are doubling down on &#34;1st class experiences&#34; with Babel (React/Ember) or Typescript (Angular2).  But Backbone at least doesn&#39;t care what transpilers you use or don&#39;t, and the other libraries are all still usable with vanilla ES5 JavaScript.
        &lt;/p&gt;
        &lt;a href=&#34;#fnref:1&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li class=&#34;footnote&#34; id=&#34;fn:2&#34;&gt;
        &lt;p&gt;
        Yes I know that classes are an ES6 feature.  But without decorators, using them with Backbone &lt;a href=&#34;http://benmccormick.org/2015/07/06/backbone-and-es6-classes-revisited/&#34;&gt;is clunky&lt;/a&gt;.
        &lt;/p&gt;
        &lt;a href=&#34;#fnref:2&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
        &lt;li class=&#34;footnote&#34; id=&#34;fn:3&#34;&gt;
            &lt;p&gt;
            In addition to other performance enhancements if an app is structured in a way that it can be determined exactly which data changed.
            &lt;/p&gt;
            &lt;a href=&#34;#fnref:3&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
        &lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Backbone and ES6 Classes Revisited</title>
      <link>https://benmccormick.org/2015/07/06/062222.html</link>
      <pubDate>Mon, 06 Jul 2015 07:22:22 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2015/07/06/062222.html</guid>
      <description>&lt;p&gt;A few weeks ago I wrote &lt;a href=&#34;http://benmccormick.org/2015/04/07/es6-classes-and-backbone-js/&#34;&gt;an article&lt;/a&gt; explaining why the final spec for classes in the ES6/ES2015 version of JavaScript was not usable in Backbone applications.  That post got a lot of great feedback, including this &lt;a href=&#34;https://github.com/jashkenas/backbone/issues/3560&#34;&gt;discussion&lt;/a&gt; with the Backbone core team. The gist of that discussion has been that there are several ways to make ES6 classes work with Backbone now, though they may be less clean than the current &lt;em&gt;Backbone.extend&lt;/em&gt; syntax.  But there&amp;rsquo;s hope for a really great experience: decorators, a &lt;a href=&#34;https://github.com/wycats/javascript-decorators&#34;&gt;proposed feature for the ES7/ES2016 spec&lt;/a&gt;, provide a much cleaner interface when working with Backbone and native classes.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s start with a quick reminder on the problem that Backbone developers face when adapting ES6 classes.  Both &lt;em&gt;Backbone.extend&lt;/em&gt; and ES6 classes serve as syntactic sugar around traditional JavaScript inheritance methods.  So the following code snippets are effectively equivalent:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; ExampleView &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; Backbone.View.extend({
    foo&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;() {
        alert(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;)
    }
});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; ExampleView &lt;span style=&#34;color:#ff79c6&#34;&gt;extends&lt;/span&gt; Backbone.View {
    foo() {
        alert(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;and each corresponds roughly to this vanilla ES5 snippet&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt; ExampleView() {
    Backbone.View.call(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;);
}

ExampleView.prototype &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;Object&lt;/span&gt;.create(Backbone.View);
ExampleView.prototype.constructor &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; Backbone.View;
ExampleView.prototype.foo &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;() {
    alert(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;);
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;All of that works fine.  The problem is that even though these abstractions are similar, they&amp;rsquo;re not quite the same.  Specifically ES6 class syntax supports an opinionated subset of what you can accomplish with plain prototype inheritance.  There&amp;rsquo;s good reason for this, since many developers don&amp;rsquo;t understand prototype inheritance and can shoot themselves in the foot.  But ES6 class restrictions don&amp;rsquo;t mesh well with Backbone&amp;rsquo;s conventions.  Specifically, Backbone relies on adding properties to a class&#39; prototype before a class&#39; constructor is invoked &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.  ES6 classes don&amp;rsquo;t provide any way to define properties on the prototype as part of the class definition.  They also do not allow you to add instance properties to a constructor prior to calling super() to run a parent class&#39; constructor.  As a result, properties that are processed within Backbone objects&#39; constructors like &lt;code&gt;events&lt;/code&gt;, &lt;code&gt;className&lt;/code&gt;, &lt;code&gt;urlRoot&lt;/code&gt; and others can&amp;rsquo;t be set within an ES6 class definition without resorting to some less than beautiful syntax.  There are however at least 3 different ways of dealing with this problem under the ES6 spec.  I&amp;rsquo;ll take a look at each of them.&lt;/p&gt;
&lt;h3 id=&#34;es6-solutions&#34;&gt;ES6 solutions&lt;/h3&gt;
&lt;p&gt;The 3 main solutions I&amp;rsquo;ve seen proposed for using the current ES6 class spec with Backbone classes are passing properties to the &lt;code&gt;super&lt;/code&gt; function, creating everything as a method, and adding properties to the prototype outside of the class definition.  I&amp;rsquo;ll go through those one by one, using &lt;a href=&#34;https://github.com/tastejs/todomvc/blob/gh-pages/examples/backbone_require/js/views/todos.js&#34;&gt;a view from one of the Backbone TodoMVC implementations&lt;/a&gt; as an example.&lt;/p&gt;
&lt;h4 id=&#34;pass-properties-to-the-super-constructor&#34;&gt;Pass properties to the super constructor&lt;/h4&gt;
&lt;p&gt;The first solution is to define a constructor function for each Backbone object that has properties, and pass the properties directly to the constructor.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;*&lt;/span&gt; as $ from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;jquery&amp;#39;&lt;/span&gt;;
&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;*&lt;/span&gt; as Backbone from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;backbone&amp;#39;&lt;/span&gt;;
&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;*&lt;/span&gt; as _ from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;underscore&amp;#39;&lt;/span&gt;;
&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;*&lt;/span&gt; as todosTemplate from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;text!templates/todos.html&amp;#39;&lt;/span&gt;;
&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;*&lt;/span&gt; as Common from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;common&amp;#39;&lt;/span&gt;;

&lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; TodoView &lt;span style=&#34;color:#ff79c6&#34;&gt;extends&lt;/span&gt; Backbone.View {

    constructor() {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;super&lt;/span&gt;({
            tagName&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;  &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;li&amp;#39;&lt;/span&gt;,

            template&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; _.template(todosTemplate),

            events&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; {
                &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;click .toggle&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;    &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;toggleCompleted&amp;#39;&lt;/span&gt;,
                &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;dblclick label&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;   &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;edit&amp;#39;&lt;/span&gt;,
                &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;click .destroy&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;   &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;clear&amp;#39;&lt;/span&gt;,
                &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;keypress .edit&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;   &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;updateOnEnter&amp;#39;&lt;/span&gt;,
                &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;keydown .edit&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;    &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;revertOnEscape&amp;#39;&lt;/span&gt;,
                &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;blur .edit&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;       &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;close&amp;#39;&lt;/span&gt;
            },
        });
    }

    initialize() {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.listenTo(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.model, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;change&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.render);
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.listenTo(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.model, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;destroy&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.remove);
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.listenTo(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.model, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;visible&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.toggleVisible);
    }

    render() {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.$el.html(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.template(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.model.toJSON()));
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.$el.toggleClass(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;completed&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.model.get(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;completed&amp;#39;&lt;/span&gt;));

        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.toggleVisible();
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.$input &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.$(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;.edit&amp;#39;&lt;/span&gt;);
        &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;;
    }

    toggleVisible() {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.$el.toggleClass(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;hidden&amp;#39;&lt;/span&gt;,  &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.isHidden());
    }

    isHidden() {
        &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; isCompleted &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.model.get(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;completed&amp;#39;&lt;/span&gt;);
        &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; (&lt;span style=&#34;color:#6272a4&#34;&gt;// hidden cases only
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;            (&lt;span style=&#34;color:#ff79c6&#34;&gt;!&lt;/span&gt;isCompleted &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; Common.TodoFilter &lt;span style=&#34;color:#ff79c6&#34;&gt;===&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;completed&amp;#39;&lt;/span&gt;) &lt;span style=&#34;color:#ff79c6&#34;&gt;||&lt;/span&gt;
            (isCompleted &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; Common.TodoFilter &lt;span style=&#34;color:#ff79c6&#34;&gt;===&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;active&amp;#39;&lt;/span&gt;)
        );
    }

    toggleCompleted() {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.model.toggle();
    }

    edit() {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.$el.addClass(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;editing&amp;#39;&lt;/span&gt;);
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.$input.focus();
    }

    close() {
        &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; value &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.$input.val();
        &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; trimmedValue &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; value.trim();

        &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (trimmedValue) {
            &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.model.save({ title&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; trimmedValue });

            &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (value &lt;span style=&#34;color:#ff79c6&#34;&gt;!==&lt;/span&gt; trimmedValue) {
                &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.model.trigger(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;change&amp;#39;&lt;/span&gt;);
            }
        } &lt;span style=&#34;color:#ff79c6&#34;&gt;else&lt;/span&gt; {
            &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.clear();
        }

        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.$el.removeClass(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;editing&amp;#39;&lt;/span&gt;);
    }

    updateOnEnter(e) {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (e.keyCode &lt;span style=&#34;color:#ff79c6&#34;&gt;===&lt;/span&gt; Common.ENTER_KEY) {
            &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.close();
        }
    }

    revertOnEscape(e) {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (e.which &lt;span style=&#34;color:#ff79c6&#34;&gt;===&lt;/span&gt; Common.ESCAPE_KEY) {
            &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.$el.removeClass(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;editing&amp;#39;&lt;/span&gt;);
            &lt;span style=&#34;color:#6272a4&#34;&gt;// Also reset the hidden input back to the original value.
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;            &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.$input.val(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.model.get(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;title&amp;#39;&lt;/span&gt;));
        }
    }

    clear() {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.model.destroy();
    }
};

&lt;span style=&#34;color:#ff79c6&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;default&lt;/span&gt; TodoView;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;There are a few advantages to this approach.  It keeps everything within the class definition, and lets Backbone itself manage attaching properties to the prototype, assuring compatibility with existing code.  However it adds a constructor call to a class that otherwise wouldn&amp;rsquo;t need one, making it less obvious when a developer is actually modifying the constructor to do something important.  It also isolates properties from methods, whereas Backbone philosophically has always treated them interchangeably.  In fact that philosophy is the key to the next solution.&lt;/p&gt;
&lt;h4 id=&#34;treat-everything-like-a-method&#34;&gt;Treat everything like a method&lt;/h4&gt;
&lt;p&gt;Backbone evaluates all of its properties using Underscore&amp;rsquo;s &lt;code&gt;_.result&lt;/code&gt; function &lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;. &lt;code&gt;_.result&lt;/code&gt; checks to see if an object property is a function. If it is then &lt;code&gt;_.result&lt;/code&gt; will evaluate it and return the result.  This allows Backbone to accept its properties as either an object or a function.  Very handy.  So one workaround to the constructor problem is to make everything a method, including properties.  We can actually go one better than this, and use the &lt;code&gt;get&lt;/code&gt; keyword to make our methods serve as &lt;em&gt;getters&lt;/em&gt; for a property.  This means they will be accessible as properties, but defined as methods, retaining compatibility with any existing references if you&amp;rsquo;re converting existing code.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; TodoView &lt;span style=&#34;color:#ff79c6&#34;&gt;extends&lt;/span&gt; Backbone.View {

    get tagName() { &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;li&amp;#39;&lt;/span&gt;}

    get template() { &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; _.template(todosTemplate)}

    get events() {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; {
            &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;click .toggle&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;    &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;toggleCompleted&amp;#39;&lt;/span&gt;,
            &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;dblclick label&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;   &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;edit&amp;#39;&lt;/span&gt;,
            &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;click .destroy&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;   &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;clear&amp;#39;&lt;/span&gt;,
            &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;keypress .edit&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;   &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;updateOnEnter&amp;#39;&lt;/span&gt;,
            &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;keydown .edit&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;    &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;revertOnEscape&amp;#39;&lt;/span&gt;,
            &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;blur .edit&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;       &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;close&amp;#39;&lt;/span&gt;
        }
    }

    initialize() {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.listenTo(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.model, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;change&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.render);
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.listenTo(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.model, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;destroy&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.remove);
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.listenTo(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.model, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;visible&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.toggleVisible);
    }

    render() {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.$el.html(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.template(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.model.toJSON()));
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.$el.toggleClass(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;completed&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.model.get(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;completed&amp;#39;&lt;/span&gt;));

        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.toggleVisible();
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.$input &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.$(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;.edit&amp;#39;&lt;/span&gt;);
        &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;;
    }

    toggleVisible() {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.$el.toggleClass(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;hidden&amp;#39;&lt;/span&gt;,  &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.isHidden());
    }

    &lt;span style=&#34;color:#6272a4&#34;&gt;//... etc
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;};

&lt;span style=&#34;color:#ff79c6&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;default&lt;/span&gt; TodoView;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This approach uses only standard class syntax, which is great.  Getters and methods are highly idiomatic class structures, and work fine with Backbone right now.  They also enforce the immutability of these properties, a design concern with the current Backbone property implementation &lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;.  But lets be real, &lt;code&gt;get tagName() { return &#39;li&#39;}&lt;/code&gt; is a significantly less clean interface than the &lt;code&gt;tagName: &#39;li&#39;&lt;/code&gt; syntax you get with &lt;em&gt;Backbone.extend&lt;/em&gt;.&lt;/p&gt;
&lt;h4 id=&#34;defining-properties-directly-on-the-prototype&#34;&gt;Defining properties directly on the prototype&lt;/h4&gt;
&lt;p&gt;The final example is the most straightforward.  Since there&amp;rsquo;s no special class syntax for adding properties to the prototype, we can just do so directly after we&amp;rsquo;ve defined the class.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; TodoView &lt;span style=&#34;color:#ff79c6&#34;&gt;extends&lt;/span&gt; Backbone.View {

    initialize() {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.listenTo(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.model, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;change&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.render);
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.listenTo(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.model, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;destroy&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.remove);
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.listenTo(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.model, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;visible&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.toggleVisible);
    }

    render() {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.$el.html(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.template(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.model.toJSON()));
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.$el.toggleClass(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;completed&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.model.get(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;completed&amp;#39;&lt;/span&gt;));

        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.toggleVisible();
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.$input &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.$(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;.edit&amp;#39;&lt;/span&gt;);
        &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;;
    }

    toggleVisible() {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.$el.toggleClass(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;hidden&amp;#39;&lt;/span&gt;,  &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.isHidden());
    }

    &lt;span style=&#34;color:#6272a4&#34;&gt;//... etc
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;};

TodoView.prototype.tagName &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;li&amp;#39;&lt;/span&gt;;
TodoView.prototype.template &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; _.template(todosTemplate);
TodoView.prototype.events &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {
    &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;click .toggle&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;    &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;toggleCompleted&amp;#39;&lt;/span&gt;,
    &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;dblclick label&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;   &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;edit&amp;#39;&lt;/span&gt;,
    &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;click .destroy&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;   &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;clear&amp;#39;&lt;/span&gt;,
    &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;keypress .edit&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;   &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;updateOnEnter&amp;#39;&lt;/span&gt;,
    &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;keydown .edit&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;    &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;revertOnEscape&amp;#39;&lt;/span&gt;,
    &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;blur .edit&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;       &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;close&amp;#39;&lt;/span&gt;
};

&lt;span style=&#34;color:#ff79c6&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;default&lt;/span&gt; TodoView;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This approach is unambiguous, but its also removes the advantages of using abstracted syntax to begin with.  Adding directly to the prototype takes properties out of the context of the class definition, making it harder to view the class as a holistic unit.  Forcing properties to appear after the class definition also breaks with Backbone community conventions.  Almost all examples of Backbone code that I&amp;rsquo;ve seen put properties at the top of Backbone class declarations, above any methods, since they&amp;rsquo;re usually important to read when trying to understand the purpose and role of an object.  They&amp;rsquo;re then followed by methods, which often contain extensive logic that is less helpful in understanding a class&#39; overall purpose.&lt;/p&gt;
&lt;p&gt;Of these 3 solutions, I personally prefer using methods and getters.  However I don&amp;rsquo;t see any of them as an improvement on the existing &lt;em&gt;Backbone.extend&lt;/em&gt; syntax.&lt;/p&gt;
&lt;h3 id=&#34;es7-and-decorators&#34;&gt;ES7 and Decorators&lt;/h3&gt;
&lt;p&gt;JavaScript is not staying stagnant however.  The TC39 committee recently approved the final spec for ES6 and is aiming to release a new spec on a yearly basis going forward.  One proposed feature for a future spec is &lt;a href=&#34;https://github.com/wycats/javascript-decorators&#34;&gt;JavaScript decorators&lt;/a&gt;.  Decorators are a declarative way of adding extra behavior to a class or class method.  They&amp;rsquo;re simple functions that take a class or method as an argument and then return an augmented version.&lt;/p&gt;
&lt;p&gt;For instance here&amp;rsquo;s a simple example from the proposal of a decorator that adds an isTestable property to classes that it decorates.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;@isTestable(&lt;span style=&#34;color:#ff79c6&#34;&gt;true&lt;/span&gt;)
&lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; MyClass { }

&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt; isTestable(value) {
   &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt; decorator(target) {
      target.isTestable &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; value;
   }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Based on that example, it&amp;rsquo;s not hard to see how this is relevant to the syntax struggle we experienced above.  Here&amp;rsquo;s a naive solution to our properties problem that utilizes a &lt;code&gt;props&lt;/code&gt; decorator to add a Backbone-esque hash of properties to the prototype.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;//decorators.js
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt; props(value) {
    &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt; decorator(target) {
        _.extend(target.prototype, value);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;*&lt;/span&gt; as $ from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;jquery&amp;#39;&lt;/span&gt;;
&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;*&lt;/span&gt; as Backbone from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;backbone&amp;#39;&lt;/span&gt;;
&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;*&lt;/span&gt; as _ from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;underscore&amp;#39;&lt;/span&gt;;
&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;*&lt;/span&gt; as todosTemplate from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;text!templates/todos.html&amp;#39;&lt;/span&gt;;
&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;*&lt;/span&gt; as Common from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;common&amp;#39;&lt;/span&gt;;
&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; {props} from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;decorators&amp;#39;&lt;/span&gt;

@props({

    tagName&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;  &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;li&amp;#39;&lt;/span&gt;,

    template&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; _.template(todosTemplate),

    events&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; {
        &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;click .toggle&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;    &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;toggleCompleted&amp;#39;&lt;/span&gt;,
        &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;dblclick label&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;   &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;edit&amp;#39;&lt;/span&gt;,
        &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;click .destroy&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;   &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;clear&amp;#39;&lt;/span&gt;,
        &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;keypress .edit&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;   &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;updateOnEnter&amp;#39;&lt;/span&gt;,
        &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;keydown .edit&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;    &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;revertOnEscape&amp;#39;&lt;/span&gt;,
        &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;blur .edit&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;       &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;close&amp;#39;&lt;/span&gt;
    },
})
&lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; TodoView &lt;span style=&#34;color:#ff79c6&#34;&gt;extends&lt;/span&gt; Backbone.View {

    initialize() {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.listenTo(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.model, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;change&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.render);
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.listenTo(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.model, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;destroy&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.remove);
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.listenTo(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.model, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;visible&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.toggleVisible);
    }

    render() {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.$el.html(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.template(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.model.toJSON()));
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.$el.toggleClass(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;completed&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.model.get(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;completed&amp;#39;&lt;/span&gt;));

        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.toggleVisible();
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.$input &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.$(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;.edit&amp;#39;&lt;/span&gt;);
        &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;;
    }

    toggleVisible() {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.$el.toggleClass(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;hidden&amp;#39;&lt;/span&gt;,  &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.isHidden());
    }

    &lt;span style=&#34;color:#6272a4&#34;&gt;//... etc
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;};

&lt;span style=&#34;color:#ff79c6&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;default&lt;/span&gt; TodoView;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That&amp;rsquo;s a big improvement over our ES6 solutions above.  Our properties are added declaratively at the top of the class and are still clearly associated with the class.  Everything lines up reasonably well with both Backbone and native idioms. This is also reminiscent of the &lt;a href=&#34;https://angular.io/docs/js/latest/quickstart.html#section-angular-create-account&#34;&gt;approach that Angular 2 is taking&lt;/a&gt; with its interface, using decorators heavily for component configuration.  It turns out though that we can actually do better.&lt;/p&gt;
&lt;p&gt;I got a tweet from Steven Langbroek last week asking me to look at his &lt;a href=&#34;https://gist.github.com/StevenLangbroek/6bd28d8201839434b843&#34;&gt;idea for using decorators to provide a cool new syntax for event binding in Backbone&lt;/a&gt;.  I thought it was awesome and it inspired me to think in a more fine grained way about using decorators with Backbone.  How can we make the syntax better, as opposed to just replicating the current experience.  Here&amp;rsquo;s what a more &amp;ldquo;fine grained&amp;rdquo; decorators approach might look like with our example.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;//decorators.js
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt; tagName(value) {
    &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt; decorator(target) {
        target.prototype.tagName &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; value;
    }
}

&lt;span style=&#34;color:#ff79c6&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt; template(value) {
    &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt; decorator(target) {
        target.prototype.template &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; _.template(value);
    }
}

&lt;span style=&#34;color:#ff79c6&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt; on(eventName){
  &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(target, name, descriptor){
    &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt;(&lt;span style=&#34;color:#ff79c6&#34;&gt;!&lt;/span&gt;target.events) {
        target.events &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {};
    }
    &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt;(_.isFunction(target.events)) {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;throw&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;Error&lt;/span&gt;(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;The on decorator is not compatible with an events method&amp;#39;&lt;/span&gt;);
        &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt;;
    }
    &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt;(&lt;span style=&#34;color:#ff79c6&#34;&gt;!&lt;/span&gt;eventName) {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;throw&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;Error&lt;/span&gt;(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;The on decorator requires an eventName argument&amp;#39;&lt;/span&gt;);
    }
    target.events[eventName] &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; name;
    &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; descriptor;
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;*&lt;/span&gt; as $ from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;jquery&amp;#39;&lt;/span&gt;;
&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;*&lt;/span&gt; as Backbone from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;backbone&amp;#39;&lt;/span&gt;;
&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;*&lt;/span&gt; as _ from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;underscore&amp;#39;&lt;/span&gt;;
&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;*&lt;/span&gt; as todosTemplate from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;text!templates/todos.html&amp;#39;&lt;/span&gt;;
&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;*&lt;/span&gt; as Common from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;common&amp;#39;&lt;/span&gt;;
&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; {tagName, template, on} from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;decorators&amp;#39;&lt;/span&gt;;

@tagName(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;li&amp;#39;&lt;/span&gt;)
@template(todosTemplate)
&lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; TodoView &lt;span style=&#34;color:#ff79c6&#34;&gt;extends&lt;/span&gt; Backbone.View {

    initialize() {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.listenTo(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.model, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;change&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.render);
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.listenTo(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.model, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;destroy&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.remove);
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.listenTo(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.model, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;visible&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.toggleVisible);
    }

    render() {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.$el.html(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.template(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.model.toJSON()));
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.$el.toggleClass(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;completed&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.model.get(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;completed&amp;#39;&lt;/span&gt;));

        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.toggleVisible();
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.$input &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.$(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;.edit&amp;#39;&lt;/span&gt;);
        &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;;
    }

    toggleVisible() {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.$el.toggleClass(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;hidden&amp;#39;&lt;/span&gt;,  &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.isHidden());
    }

    isHidden() {
        &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; isCompleted &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.model.get(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;completed&amp;#39;&lt;/span&gt;);
        &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; (&lt;span style=&#34;color:#6272a4&#34;&gt;// hidden cases only
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;            (&lt;span style=&#34;color:#ff79c6&#34;&gt;!&lt;/span&gt;isCompleted &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; Common.TodoFilter &lt;span style=&#34;color:#ff79c6&#34;&gt;===&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;completed&amp;#39;&lt;/span&gt;) &lt;span style=&#34;color:#ff79c6&#34;&gt;||&lt;/span&gt;
            (isCompleted &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; Common.TodoFilter &lt;span style=&#34;color:#ff79c6&#34;&gt;===&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;active&amp;#39;&lt;/span&gt;)
        );
    }

    @on(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;click .toggle&amp;#39;&lt;/span&gt;)
    toggleCompleted() {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.model.toggle();
    }

    @on(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;dblclick label&amp;#39;&lt;/span&gt;)
    edit() {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.$el.addClass(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;editing&amp;#39;&lt;/span&gt;);
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.$input.focus();
    }

    @on(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;blur .edit&amp;#39;&lt;/span&gt;)
    close() {
        &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; value &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.$input.val();
        &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; trimmedValue &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; value.trim();

        &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (trimmedValue) {
            &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.model.save({ title&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; trimmedValue });

            &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (value &lt;span style=&#34;color:#ff79c6&#34;&gt;!==&lt;/span&gt; trimmedValue) {
                &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.model.trigger(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;change&amp;#39;&lt;/span&gt;);
            }
        } &lt;span style=&#34;color:#ff79c6&#34;&gt;else&lt;/span&gt; {
            &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.clear();
        }

        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.$el.removeClass(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;editing&amp;#39;&lt;/span&gt;);
    }

    @on(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;keypress .edit&amp;#39;&lt;/span&gt;)
    updateOnEnter(e) {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (e.keyCode &lt;span style=&#34;color:#ff79c6&#34;&gt;===&lt;/span&gt; Common.ENTER_KEY) {
            &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.close();
        }
    }

    @on(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;keydown .edit&amp;#39;&lt;/span&gt;)
    revertOnEscape(e) {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (e.which &lt;span style=&#34;color:#ff79c6&#34;&gt;===&lt;/span&gt; Common.ESCAPE_KEY) {
            &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.$el.removeClass(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;editing&amp;#39;&lt;/span&gt;);
            &lt;span style=&#34;color:#6272a4&#34;&gt;// Also reset the hidden input back to the original value.
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;            &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.$input.val(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.model.get(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;title&amp;#39;&lt;/span&gt;));
        }
    }

    @on(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;click .destroy&amp;#39;&lt;/span&gt;)
    clear() {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.model.destroy();
    }
};

&lt;span style=&#34;color:#ff79c6&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;default&lt;/span&gt; TodoView;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now we&amp;rsquo;re getting somewhere.  Steven&amp;rsquo;s &lt;code&gt;on&lt;/code&gt; decorator provides a really nice upgrade to Backbone&amp;rsquo;s event system.  Event handlers are now in the context of the methods they refer to, making it much easier to get context as you scroll through a large view.  Our tagName gets a nice declarative setter at the top of the view rather than being bundled into an object hash.  And our template processing gets standardized, with the call to &lt;code&gt;_.template&lt;/code&gt; abstracted away into the decorator.  That last decorator would probably be project specific, but the other 2 could easily be incorporated into a general Backbone decorator library.&lt;/p&gt;
&lt;p&gt;The main downside I see to this is one shared by a few of the other approaches.  Specifically that declaring a property like tagName as a method or as a property requires different implementation styles.  Backbone philosophically treats these scenarios as equivalent, and its not unusual to start with a static property for keys like &lt;code&gt;className&lt;/code&gt;, &lt;code&gt;url&lt;/code&gt;, or &lt;code&gt;template&lt;/code&gt; and then refactor to use a function as code is reused in different situations.  Artificially separating out those scenarios is not very Backbone-like and might discourage that type of refactoring.&lt;/p&gt;
&lt;h3 id=&#34;recommendations&#34;&gt;Recommendations&lt;/h3&gt;
&lt;p&gt;If you want to use ES6 classes with Backbone in production today, you should probably make everything a method, and make liberal use of the getter functionality.  That seems to be the most Backbone-like, with everything contained in a single class definition, and easy refactoring when a property begins to require logic around it.  If you&amp;rsquo;re experimenting though, you should definitely consider playing with decorators and see how you can make Backbone&amp;rsquo;s interface better.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;If you have ideas about this, feel free to contribute on the &lt;a href=&#34;https://github.com/jashkenas/backbone/issues/3560&#34;&gt;github issue&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;div class=&#34;footnotes&#34;&gt;
&lt;ol&gt;
    &lt;li class=&#34;footnote&#34; id=&#34;fn:1&#34;&gt;
        &lt;p&gt;
        I completely screwed up explaining this in my first piece.  I was under the mistaken impression that Backbone was adding properties like `className` and `events` to each instance rather than to the prototype.  Which makes no sense in retrospect, since those properties need to be present before the Backbone.View is run.
        &lt;a href=&#34;#fnref:1&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
        &lt;li class=&#34;footnote&#34; id=&#34;fn:2&#34;&gt;
            &lt;p&gt;
            Well, almost all. iDAttribute &lt;a href=&#34;https://github.com/jashkenas/backbone/pull/3684&#34;&gt;is still catching up&lt;/a&gt;.
            &lt;a href=&#34;#fnref:2&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
        &lt;/li&gt;
        &lt;li class=&#34;footnote&#34; id=&#34;fn:3&#34;&gt;
            &lt;p&gt;
            Oh you didn&#39;t realize that adding an item to the event hash for your view would add it to every instance of that View?  Whoops.
            &lt;a href=&#34;#fnref:3&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
        &lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Book Review: Talking with Tech Leads</title>
      <link>https://benmccormick.org/2015/06/15/063044.html</link>
      <pubDate>Mon, 15 Jun 2015 07:30:44 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2015/06/15/063044.html</guid>
      <description>&lt;p&gt;Can we be honest for a moment?  Figuring out a career path is hard for software developers.  Talking to some people, you&amp;rsquo;ll get the impression that we face a pretty bleak binary choice.  Behind door number #1 lies a relatively rapid path to a &amp;ldquo;senior developer&amp;rdquo; role, followed by stagnation the rest of your career as you reimplement the same solutions in new technologies for minimally increasing pay over time, until youth-friendly tech culture decides that you&amp;rsquo;re too old to be useful.  Door #2 serves basically as an escape hatch, as you trade the opportunity to work with code for a path into management, where you receive a few more pay raises in return for your soul.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;twtl.png&#34; alt=&#34;Talking with Tech Leads Cover&#34;&gt;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m not that cynical, and hopefully not that dramatic, but as a relatively young developer it&amp;rsquo;s been hard to figure out what I want from a career and harder still to know exactly what different options would look like if I got there.  I know that I love technology; at the same time I want to have real influence on the things that I&amp;rsquo;m building, and in most places it&amp;rsquo;s the product and people challenges that ultimately determine whether software projects succeed or fail, rather than the pure technical ones.  So what does it look like to build a career leading across these different areas? That&amp;rsquo;s the question that &lt;a href=&#34;https://leanpub.com/talking-with-tech-leads?a=3a4Srv2pP9p87WQ_eoDoGp&#34;&gt;Talking with Tech Leads&lt;/a&gt; tries to answer.&lt;/p&gt;
&lt;p&gt;Talking with Tech Leads is an eBook about what it&amp;rsquo;s like to pursue a middle path between the two sides of the false dichotomy above.  It&amp;rsquo;s structured as a series of interviews with &amp;ldquo;Tech Leads&amp;rdquo;, which the author defines as &lt;a href=&#34;https://www.thekua.com/atwork/2014/11/the-definition-of-a-tech-lead/&#34;&gt;a developer leading a development team&lt;/a&gt;.  Each interview shares a series of questions, as well as an open space for interviewees to share more freeform thoughts and advice.&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;What should a Tech Lead focus on and why?&lt;/li&gt;
&lt;li&gt;What has been your biggest challenge as a Tech Lead?&lt;/li&gt;
&lt;li&gt;Any time-management tips?&lt;/li&gt;
&lt;li&gt;How do you strike the right balance between writing code and dealing with other issues?&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;As you would expect from a series of nearly forty interviews with the same structure, there is plenty of repetition across answers.  Themes emerge quickly: a need to look beyond code for solutions without losing sight of your technical skills, the importance of enabling your team members to succeed, and the need to bridge the communication gap between technical and non-technical participants in a business.  At the same time it&amp;rsquo;s clear that many of these individuals view their roles drastically differently despite superficially similar job descriptions.  Some focus on leading people, some on software architecture, and some on aligning business and technical objectives.  What the interviews expose are a wide and varied set of niches that fall between the traditional &amp;ldquo;Senior Developer&amp;rdquo; and &amp;ldquo;Management&amp;rdquo; career paths.&lt;/p&gt;
&lt;p&gt;I have no idea how this book would read to a seasoned tech lead.  I expect that it would be affirming to see how others have approached similar challenges, but I&amp;rsquo;m not sure it does a good enough job pulling the various threads from the interview into practical insights to provide much tangible big picture advice for current tech leads.  Instead it would likely be a collection of small useful ideas and nuggets.&lt;/p&gt;
&lt;p&gt;For a developer like myself who is still figuring out what it looks like to have a career in this industry though, this book is a tapestry of ideas and possibilities.  I&amp;rsquo;d recommend it to anyone who&amp;rsquo;s been underwhelmed by the extreme career paths that serve as the &amp;ldquo;path of least resistance&amp;rdquo; in some organizations, and want to become leaders without sacrificing their roots.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;You can purchase Talking with Tech Leads as an e-book through &lt;a href=&#34;https://leanpub.com/talking-with-tech-leads?a=3a4Srv2pP9p87WQ_eoDoGp&#34;&gt;Leanpub&lt;/a&gt; or as a paperback on &lt;a href=&#34;http://amzn.to/1KQdC90&#34;&gt;Amazon&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Mozilla: The state of Web Components</title>
      <link>https://benmccormick.org/2015/06/14/163558.html</link>
      <pubDate>Sun, 14 Jun 2015 17:35:58 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2015/06/14/163558.html</guid>
      <description>&lt;p&gt;Over on Mozilla&amp;rsquo;s development blog, Wilson Page has a &lt;a href=&#34;https://hacks.mozilla.org/2015/06/the-state-of-web-components/&#34;&gt;great summary&lt;/a&gt; of the current status of the Web Components spec:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Web Components have been on developers’ radars for quite some time now. They were first introduced by Alex Russell at Fronteers Conference 2011. The concept shook the community up and became the topic of many future talks and discussions.&lt;/p&gt;
&lt;p&gt;In 2013 a Web Components-based framework called Polymer was released by Google to kick the tires of these new APIs, get community feedback and add some sugar and opinion.&lt;/p&gt;
&lt;p&gt;By now, 4 years on, Web Components should be everywhere, but in reality Chrome is the only browser with ‘some version’ of Web Components. Even with polyfills it’s clear Web Components won’t be fully embraced by the community until the majority of browsers are on-board.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I&amp;rsquo;ve been using Custom Elements (the least controversial part of the Web Components spec) in production for a little less than a year now thanks to a &lt;a href=&#34;https://github.com/WebReflection/document-register-element&#34;&gt;small polyfill script&lt;/a&gt;.  I know that many others are using a version of them through &lt;a href=&#34;https://www.polymer-project.org/1.0/&#34;&gt;Polymer&lt;/a&gt;.  It&amp;rsquo;s been sad to see the spec stagnate without browser support for much longer than might have been expected, but it seems there&amp;rsquo;s reason for hope.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Web Components have been in planning for over three years, but we’re optimistic the end is near. All major vendors are on board, enthusiastic, and investing significant time to help resolve the remaining issues.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It&amp;rsquo;s exciting to see public cooperation on this issue, something that was not very visible over the past few years as Chrome fired ahead with an implementation while others pursued other priorities.  If you care about this spec at all, make sure to read &lt;a href=&#34;https://hacks.mozilla.org/2015/06/the-state-of-web-components/&#34;&gt;the full article&lt;/a&gt;.  It&amp;rsquo;s an interesting look at where the spec may be going as well as a nice peak behind the scenes of how web APIs become established.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Is Safari being left behind?</title>
      <link>https://benmccormick.org/2015/06/09/230341.html</link>
      <pubDate>Wed, 10 Jun 2015 00:03:41 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2015/06/10/230341.html</guid>
      <description>&lt;p&gt;On Twitter yesterday, &lt;a href=&#34;https://alexsexton.com/&#34;&gt;Alex Sexton&lt;/a&gt; surfaced Apple&amp;rsquo;s fact sheet on what&amp;rsquo;s new with Safari 9:&lt;/p&gt;
&lt;blockquote class=&#34;twitter-tweet&#34; lang=&#34;en&#34;&gt;&lt;p lang=&#34;en&#34; dir=&#34;ltr&#34;&gt;&lt;a href=&#34;https://t.co/fVg9U9dEq4&#34;&gt;https://t.co/fVg9U9dEq4&lt;/a&gt;&amp;#10;&amp;#10;Some ES6 and lots of unprefixed CSS (flexbox!), but I really want Intl, ServiceWorkers, PointerEvents, HTTP2, CSP2…&lt;/p&gt;&amp;mdash; Alex Sexton (@SlexAxton) &lt;a href=&#34;https://twitter.com/SlexAxton/status/608017541173284864&#34;&gt;June 8, 2015&lt;/a&gt;&lt;/blockquote&gt;
&lt;p&gt;Safari 9 is still in developer preview and won&amp;rsquo;t ship till September or so, so this all could change, but Apple&amp;rsquo;s changelog is underwhelming to say the least.   The developer facing changes in Safari 9 consist of only standardized versions of CSS properties (that were already supported with a prefix), and a handful of ES6 features.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The following ECMAScript 6 content is now supported by Safari:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Classes&lt;/li&gt;
&lt;li&gt;Computed Properties&lt;/li&gt;
&lt;li&gt;Weak Set&lt;/li&gt;
&lt;li&gt;Number Object&lt;/li&gt;
&lt;li&gt;Octal and Binary Literals&lt;/li&gt;
&lt;li&gt;Symbol Objects&lt;/li&gt;
&lt;li&gt;Template Literals&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;em&gt;- &lt;a href=&#34;https://developer.apple.com/library/prerelease/mac/releasenotes/General/WhatsNewInSafari/Articles/Safari_9.html#//apple_ref/doc/uid/TP40014305-CH9-SW27&#34;&gt;Safari Pre-Release notes&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;While it&amp;rsquo;s great to see ES6 support, the truth is that by the time Safari is released in the fall, &lt;a href=&#34;http://blogs.windows.com/msedgedev/2015/05/12/javascript-moves-forward-in-microsoft-edge-with-ecmascript-6-and-beyond/&#34;&gt;Microsoft Edge&lt;/a&gt; will have been released, and Safari 9 will release as (at best) the &lt;a href=&#34;http://kangax.github.io/compat-table/es6/&#34;&gt;3rd most ES6-compliant browser&lt;/a&gt; among the 4 major desktop browsers.  And due to its yearly schedule, it&amp;rsquo;s basically guaranteed to be in last by the end of the year.  At the same time Safari has neglected other APIs like Internationalization, Pointer Events, Web Components, CSS Variables, Service Workers, or ASM.js optimizations, all of which are supported or in progress by each of the other browsers &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.  In addition, Safari&amp;rsquo;s developer tools, which were once best in class, have been slowly falling behind Chrome and Firefox, especially in more advanced performance features.&lt;/p&gt;
&lt;p&gt;So does this mean that Safari is the next IE6?  Not so much.  We&amp;rsquo;ve come a long way since the IE6 era, and browsers are more standards compliant than ever.  Tools like &lt;a href=&#34;https://babeljs.io/&#34;&gt;Babel&lt;/a&gt; make it easier for developers to participate in the future of the web without being restricted by slow moving browsers or legacy support concerns.   But there&amp;rsquo;s always going to be some browser that serves as the &amp;ldquo;bottleneck&amp;rdquo; for what web developers are able to reasonably use in production.  Currently that is older versions of Internet Explorer and old Android browsers.  But as more and more users upgrade to Android phones using Chrome, and Microsoft makes strong pushes to move users to the &lt;a href=&#34;http://benmccormick.org/2013/06/11/evergreen-browsers/&#34;&gt;evergreen&lt;/a&gt; Edge browser, it&amp;rsquo;s quite likely that Safari could take their place.  It is now the only major browser being updated yearly, and with Microsoft&amp;rsquo;s recent re-emphasis on JavaScript and HTML development, Apple is the only major browser vendor who seems to view the web as a second class platform.&lt;/p&gt;
&lt;p&gt;Safari is not going away.  Its monopoly status on iOS more or less guarantees that, and on the desktop I&amp;rsquo;ve talked to plenty of people who like its simple UI, and others who feel that it&amp;rsquo;s faster or consumes less memory than Chrome and Firefox.  But it will be a sad sight if it gets left behind.  Here&amp;rsquo;s hoping that the final release contains more surprises, and that going forward Apple chooses to embrace the web browser as a platform worthy of the respect and effort its competitors have lavished on it.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34;&gt;
&lt;ol&gt;
    &lt;li class=&#34;footnote&#34; id=&#34;fn:1&#34;&gt;
        &lt;p&gt;
        Ok, CSS Variables, Service Workers and Web Components are &#34;under consideration&#34; by IE.
        &lt;a href=&#34;#fnref:1&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>How jQuery Works - An Introduction</title>
      <link>https://benmccormick.org/2015/06/08/065125.html</link>
      <pubDate>Mon, 08 Jun 2015 07:51:25 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2015/06/08/065125.html</guid>
      <description>&lt;p&gt;Every developer has had the experience of using &amp;ldquo;magic&amp;rdquo; code.  Not the &amp;ldquo;hacked into the NSA in 20 seconds&amp;rdquo; type of magic code you see in movies. This is the code created when you nervously typed an incomprehensible incantation that somebody else passed on to you, desperately hoping to receive the results you want, ignoring the sinking feeling in your stomach that you have no clue what to do if it fails.  Almost all code feels like this when you&amp;rsquo;re pushing out to learn new things.  But it doesn&amp;rsquo;t have to stay that way.&lt;/p&gt;
&lt;p&gt;The primary goal of this blog has always been to help myself understand the tools I&amp;rsquo;m using, and to share that understanding with as many people as possible.  My experience is that really understanding a library or framework requires diving into the source code and swimming around a bit. Which sounds great.  But often the real world gets in the way. Real world source code is full of &amp;ldquo;special code&amp;rdquo;.  Code that handles browser edge cases, performance optimizations that obscure meaning, indirection to allow shared solutions for common problems; all things that are completely necessary, and also likely to obscure the true structure of code.  So while reading the source is the best way to understand a library, it often helps to have some guideposts to lead you through.&lt;/p&gt;
&lt;p&gt;This post is the start of a new series diving into how jQuery (certainly a very magical library for many developers) works.  I&amp;rsquo;ll pull snippets from the source code, but also try to lay out the big picture approaches the library takes to provide functionality that combines to form by far the best-known and most used JavaScript library out there &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;. For this introduction, the focus will be on the overall structure of the jQuery repository, how the code is laid out for development purposes, how it&amp;rsquo;s built into a single file for production use, and a quick look at the core jQuery object code.  Future posts will cover how different features of the libary work, including deep dives into selectors, ajax, animation, and events.&lt;/p&gt;
&lt;h3 id=&#34;so-where-to-start&#34;&gt;So where to start?&lt;/h3&gt;
&lt;p&gt;When you look at the &lt;a href=&#34;https://github.com/jquery/jquery&#34;&gt;jQuery Github repo&lt;/a&gt;, one of the first things you&amp;rsquo;ll probably notice is that the source isn&amp;rsquo;t developed as a single file the way it is distributed.  Instead it&amp;rsquo;s split up into many files separated by functionality.  That makes it easier to find specific functions when you know what you&amp;rsquo;re looking for, but harder to know where to start when trying to understand the big picture.  If you&amp;rsquo;re new to the library, it could be overwhelming.&lt;/p&gt;
&lt;p&gt;Fortunately it&amp;rsquo;s not that hard to get the lay of the land.  jQuery is broken into modules using the AMD format, and built using requireJS.  So each file lists its dependencies, and it&amp;rsquo;s easy enough to trace back what code is referenced where. So we can start by looking at &lt;code&gt;src/jquery.js&lt;/code&gt;, which serves simply as a base file to require all of the other dependencies, then make the jQuery namespace available globally, both as &lt;code&gt;jQuery&lt;/code&gt; and the famous &lt;code&gt;$&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;jquery_js.png&#34; alt=&#34;jquery_js.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;From that file we can see the layout of the library.  The core file is loaded and attached to the window, and all of the other &amp;ldquo;feature files&amp;rdquo; are also listed as dependencies to make sure they load.  Each of those files lists &lt;code&gt;core.js&lt;/code&gt; as a dependency, so it is loaded first and creates the main jQuery namespace, which other dependencies then edit as needed.  If you&amp;rsquo;re interested in the process of how the package is built, you can take a read through &lt;a href=&#34;https://github.com/jquery/jquery/blob/master/build/tasks/build.js&#34;&gt;build/tasks/build.js&lt;/a&gt;, where the dependencies are built using requirejs &lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;h3 id=&#34;a-look-at-corejs&#34;&gt;A look at core.js&lt;/h3&gt;
&lt;p&gt;We can see from jquery.js that &lt;a href=&#34;https://github.com/jquery/jquery/blob/master/src/core.js&#34;&gt;core.js&lt;/a&gt; is an important file.  It exports the main jQuery namespace, and if we look around we&amp;rsquo;ll see that it is required by about half of the files in the source directory as a dependency.  So what does it do?  core.js is responsible for defining the jQuery namespace, as well as the prototype for jQuery objects.  This is a great place to start before taking a more detailed look into the library&amp;rsquo;s features, so lets take a look.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;define([
	&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;./var/arr&amp;#34;&lt;/span&gt;,
	&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;./var/document&amp;#34;&lt;/span&gt;,
	&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;./var/slice&amp;#34;&lt;/span&gt;,
	&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;./var/concat&amp;#34;&lt;/span&gt;,
	&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;./var/push&amp;#34;&lt;/span&gt;,
	&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;./var/indexOf&amp;#34;&lt;/span&gt;,
	&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;./var/class2type&amp;#34;&lt;/span&gt;,
	&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;./var/toString&amp;#34;&lt;/span&gt;,
	&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;./var/hasOwn&amp;#34;&lt;/span&gt;,
	&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;./var/support&amp;#34;&lt;/span&gt;
], &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;( arr, &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;document&lt;/span&gt;, slice, concat, push, indexOf, class2type, toString, hasOwn, support ) {

&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt;
	version &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;@VERSION&amp;#34;&lt;/span&gt;,

	&lt;span style=&#34;color:#6272a4&#34;&gt;// Define a local copy of jQuery
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;	jQuery &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;( selector, context ) {
		&lt;span style=&#34;color:#6272a4&#34;&gt;// The jQuery object is actually just the init constructor &amp;#39;enhanced&amp;#39;
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;		&lt;span style=&#34;color:#6272a4&#34;&gt;// Need init if jQuery is called (just allow error to be thrown if not included)
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;		&lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; jQuery.fn.init( selector, context );
	},
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;There&amp;rsquo;s a lot going on in the first 20 or so lines.  First we see a pattern that will repeat in future files.  jQuery uses a lot of small utility functions throughout its code.  Rather than attaching those to a single object, each one gets its own file in the &lt;code&gt;var&lt;/code&gt; directory, and then is imported as a dependency as needed.  These modules are typically quite small and often trivial.  For instance the document module that is pulled in from &lt;code&gt;var/document&lt;/code&gt; consists in its entirety of the following code:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;define(&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;() {
	&lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;window&lt;/span&gt;.&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;document&lt;/span&gt;;
});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is obviously a small shortcut, but it allows for consistent use of a pattern across the library. You&amp;rsquo;ll see small utility modules like this loaded in every significant file throughout the source code.&lt;/p&gt;
&lt;p&gt;After the imports, this file sets the version (the @VERSION annotation is replaced with the version number as part of the build process), and then creates the base jQuery function.  That base function proxies out to the &lt;code&gt;init&lt;/code&gt; function if it is available, but more importantly serves as a namespace for the rest of the library.  All future functionality gets extended off of this object or its prototype.  After setting up a few constants, we dive right into that:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;jQuery.fn = jQuery.prototype = {
	// The current version of jQuery being used
	jquery: version,

	constructor: jQuery,

	// The default length of a jQuery object is 0
	length: 0,

	toArray: function() {
		return slice.call( this );
	},

	// Get the Nth element in the matched element set OR
	// Get the whole matched element set as a clean array
	get: function( num ) {
		return num != null ?

			// Return just the one element from the set
			( num &amp;lt; 0 ? this[ num + this.length ] : this[ num ] ) :

			// Return all the elements in a clean array
			slice.call( this );
	},

	// Take an array of elements and push it onto the stack
	// (returning the new matched element set)
	pushStack: function( elems ) {

		// Build a new jQuery matched element set
		var ret = jQuery.merge( this.constructor(), elems );

		// Add the old object onto the stack (as a reference)
		ret.prevObject = this;

		// Return the newly-formed element set
		return ret;
	},

	// Execute a callback for every element in the matched set.
	each: function( callback ) {
		return jQuery.each( this, callback );
	},

	map: function( callback ) {
		return this.pushStack( jQuery.map(this, function( elem, i ) {
			return callback.call( elem, i, elem );
		}));
	},

	slice: function() {
		return this.pushStack( slice.apply( this, arguments ) );
	},

	first: function() {
		return this.eq( 0 );
	},

	last: function() {
		return this.eq( -1 );
	},

	eq: function( i ) {
		var len = this.length,
			j = +i + ( i &amp;lt; 0 ? len : 0 );
		return this.pushStack( j &amp;gt;= 0 &amp;amp;&amp;amp; j &amp;lt; len ? [ this[j] ] : [] );
	},

	end: function() {
		return this.prevObject || this.constructor(null);
	},

	// For internal use only.
	// Behaves like an Array&#39;s method, not like a jQuery method.
	push: push,
	sort: arr.sort,
	splice: arr.splice
};
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Here the code sets up the jQuery prototype, which is also made available as &lt;code&gt;jQuery.fn&lt;/code&gt;.  jQuery objects, what you get when you select a set of elements with jQuery, have access to all of the methods defined on this prototype.  &lt;code&gt;jQuery.fn&lt;/code&gt; is also the extension point for jQuery plugins, so that custom functions are available to jQuery objects.  Most of the functions built here are pretty basic ones that mimic built in array functions for jQuery objects.&lt;/p&gt;
&lt;h3 id=&#34;a-note-about-jquery-objects&#34;&gt;A note about jQuery objects&lt;/h3&gt;
&lt;p&gt;I&amp;rsquo;ve glossed over jQuery objects twice now, but we&amp;rsquo;ve seen enough already to get a deeper understanding of what they are.  jQuery objects are the objects created when the jQuery init function is used as a constructor to create a new object &lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;.  That sounds fancy, but in reality that&amp;rsquo;s what is happening every time you make a simple jQuery call like &lt;code&gt;$(&#39;#foo&#39;)&lt;/code&gt; or &lt;code&gt;$(&#39;div&#39;)&lt;/code&gt;.  The jQuery namespace function is being called and returns a new object with &lt;code&gt;jQuery.init&lt;/code&gt; as the constructor.  Since &lt;code&gt;init&lt;/code&gt; shares a prototype with the namespace function &lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;, these objects all have access to &lt;code&gt;jQuery.prototype&lt;/code&gt;.  The second post in this series will talk more about how the init function parses the various inputs that you can pass to the namespace function, but for now it&amp;rsquo;s best to focus on understanding that the namespace function and jQuery.fn are not magic, but are just a wrapper and alias for portions of a fairly normal prototypical inheritance example in JavaScript.&lt;/p&gt;
&lt;h3 id=&#34;extend&#34;&gt;Extend&lt;/h3&gt;
&lt;p&gt;After the base functions get added to the prototype, a special function is created and added to both the prototype and the namespace function directly.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;
jQuery.extend &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; jQuery.fn.extend &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;() {
	&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; options, name, src, copy, copyIsArray, clone,
		target &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; arguments[&lt;span style=&#34;color:#bd93f9&#34;&gt;0&lt;/span&gt;] &lt;span style=&#34;color:#ff79c6&#34;&gt;||&lt;/span&gt; {},
		i &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;,
		length &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; arguments.length,
		deep &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;false&lt;/span&gt;;

	&lt;span style=&#34;color:#6272a4&#34;&gt;// Handle a deep copy situation
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;	&lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; ( &lt;span style=&#34;color:#ff79c6&#34;&gt;typeof&lt;/span&gt; target &lt;span style=&#34;color:#ff79c6&#34;&gt;===&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;boolean&amp;#34;&lt;/span&gt; ) {
		deep &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; target;

		&lt;span style=&#34;color:#6272a4&#34;&gt;// Skip the boolean and the target
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;		target &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; arguments[ i ] &lt;span style=&#34;color:#ff79c6&#34;&gt;||&lt;/span&gt; {};
		i&lt;span style=&#34;color:#ff79c6&#34;&gt;++&lt;/span&gt;;
	}

	&lt;span style=&#34;color:#6272a4&#34;&gt;// Handle case when target is a string or something (possible in deep copy)
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;	&lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; ( &lt;span style=&#34;color:#ff79c6&#34;&gt;typeof&lt;/span&gt; target &lt;span style=&#34;color:#ff79c6&#34;&gt;!==&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;object&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;!&lt;/span&gt;jQuery.isFunction(target) ) {
		target &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {};
	}

	&lt;span style=&#34;color:#6272a4&#34;&gt;// Extend jQuery itself if only one argument is passed
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;	&lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; ( i &lt;span style=&#34;color:#ff79c6&#34;&gt;===&lt;/span&gt; length ) {
		target &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;;
		i&lt;span style=&#34;color:#ff79c6&#34;&gt;--&lt;/span&gt;;
	}

	&lt;span style=&#34;color:#ff79c6&#34;&gt;for&lt;/span&gt; ( ; i &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt; length; i&lt;span style=&#34;color:#ff79c6&#34;&gt;++&lt;/span&gt; ) {
		&lt;span style=&#34;color:#6272a4&#34;&gt;// Only deal with non-null/undefined values
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;		&lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; ( (options &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; arguments[ i ]) &lt;span style=&#34;color:#ff79c6&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;null&lt;/span&gt; ) {
			&lt;span style=&#34;color:#6272a4&#34;&gt;// Extend the base object
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;			&lt;span style=&#34;color:#ff79c6&#34;&gt;for&lt;/span&gt; ( name &lt;span style=&#34;color:#ff79c6&#34;&gt;in&lt;/span&gt; options ) {
				src &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; target[ name ];
				copy &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; options[ name ];

				&lt;span style=&#34;color:#6272a4&#34;&gt;// Prevent never-ending loop
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;				&lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; ( target &lt;span style=&#34;color:#ff79c6&#34;&gt;===&lt;/span&gt; copy ) {
					&lt;span style=&#34;color:#ff79c6&#34;&gt;continue&lt;/span&gt;;
				}

				&lt;span style=&#34;color:#6272a4&#34;&gt;// Recurse if we&amp;#39;re merging plain objects or arrays
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;				&lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; ( deep &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; copy &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; ( jQuery.isPlainObject(copy) &lt;span style=&#34;color:#ff79c6&#34;&gt;||&lt;/span&gt;
					(copyIsArray &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; jQuery.isArray(copy)) ) ) {

					&lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; ( copyIsArray ) {
						copyIsArray &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;false&lt;/span&gt;;
						clone &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; src &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; jQuery.isArray(src) &lt;span style=&#34;color:#ff79c6&#34;&gt;?&lt;/span&gt; src &lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; [];

					} &lt;span style=&#34;color:#ff79c6&#34;&gt;else&lt;/span&gt; {
						clone &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; src &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; jQuery.isPlainObject(src) &lt;span style=&#34;color:#ff79c6&#34;&gt;?&lt;/span&gt; src &lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; {};
					}

					&lt;span style=&#34;color:#6272a4&#34;&gt;// Never move original objects, clone them
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;					target[ name ] &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; jQuery.extend( deep, clone, copy );

				&lt;span style=&#34;color:#6272a4&#34;&gt;// Don&amp;#39;t bring in undefined values
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;				} &lt;span style=&#34;color:#ff79c6&#34;&gt;else&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; ( copy &lt;span style=&#34;color:#ff79c6&#34;&gt;!==&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;undefined&lt;/span&gt; ) {
					target[ name ] &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; copy;
				}
			}
		}
	}

	&lt;span style=&#34;color:#6272a4&#34;&gt;// Return the modified object
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;	&lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; target;
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;$.extend&lt;/code&gt; is jQuery&amp;rsquo;s way of merging properties from one object into another.  It&amp;rsquo;s also a very handy shortcut for cloning an object (&lt;code&gt;var clone = $.extend({},obj)&lt;/code&gt;).  We&amp;rsquo;ll see an example usage shortly, but since it&amp;rsquo;s a common function, it&amp;rsquo;s worth digging into how it works for a second.&lt;/p&gt;
&lt;p&gt;Looking at the code above, we can see that extend takes a variable number of arguments, the first of which can optionally be a boolean telling the function to &amp;ldquo;deep copy&amp;rdquo;.  If only a single object is passed, the function acts as if the jQuery prototype was passed as the first object, and targets that, otherwise it targets the first non-boolean argument.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;extend&lt;/code&gt; then loops over each argument after the target and for each one goes over each of its keys.  For each object in order, properties are copied from the arguments to the target object.  If deep copy is set, properties that are objects are merged by calling &lt;code&gt;extend&lt;/code&gt; recursively.  Otherwise, existing properties are overwritten.  This continues left to right till all arguments have been merged.&lt;/p&gt;
&lt;p&gt;The source code helpfully gives us an immediate example of how &lt;code&gt;extend&lt;/code&gt; can be useful.  jQuery makes several properties and helpful functions available directly off of the &lt;code&gt;$&lt;/code&gt; namespace.  Several of them are added here using extend.  You can see how the object notation flows much better than a long series of assignments with &lt;code&gt;=&lt;/code&gt; would.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;jQuery.extend({
	&lt;span style=&#34;color:#6272a4&#34;&gt;// Unique for each copy of jQuery on the page
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;	expando&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;jQuery&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; ( version &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;Math&lt;/span&gt;.random() ).replace( &lt;span style=&#34;color:#f1fa8c&#34;&gt;/\D/g&lt;/span&gt;, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt; ),

	&lt;span style=&#34;color:#6272a4&#34;&gt;// Assume jQuery is ready without the ready module
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;	isReady&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;true&lt;/span&gt;,

	error&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;( msg ) {
		&lt;span style=&#34;color:#ff79c6&#34;&gt;throw&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;Error&lt;/span&gt;( msg );
	},

	noop&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;() {},

	isFunction&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;( obj ) {
		&lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; jQuery.type(obj) &lt;span style=&#34;color:#ff79c6&#34;&gt;===&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;function&amp;#34;&lt;/span&gt;;
	},

	isArray&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;Array&lt;/span&gt;.isArray,

	isWindow&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;( obj ) {
		&lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; obj &lt;span style=&#34;color:#ff79c6&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;null&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; obj &lt;span style=&#34;color:#ff79c6&#34;&gt;===&lt;/span&gt; obj.&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;window&lt;/span&gt;;
	},

	&lt;span style=&#34;color:#6272a4&#34;&gt;//... many more functions and properties here
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;After working through 2 more helper functions, the namespace object gets returned, wrapping up &lt;code&gt;core.js&lt;/code&gt;.  So 2 files and ~500 lines of source code in, we already have a pretty good idea of how jQuery is structured, both in terms of using AMD modules to separate out the source, and using a namespace function and its prototype as a central object to attach functionality.&lt;/p&gt;
&lt;h3 id=&#34;more-resources&#34;&gt;More Resources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;It&amp;rsquo;s no longer maintained with newer versions, but a few years ago Rob Flaherty created an annotated version of jQuery 1.6&amp;rsquo;s source.  You can see that &lt;a href=&#34;http://robflaherty.github.io/jquery-annotated-source/&#34;&gt;here&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Along the same lines: John Resig, jQuery&amp;rsquo;s creator, recently went through his original jQuery library (a early ~1.0 version) and &lt;a href=&#34;http://ejohn.org/blog/annotated-version-of-the-original-jquery-release/&#34;&gt;annotated it with both code commentary and historical notes&lt;/a&gt;. It&amp;rsquo;s a great look inside the history of the library.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;footnotes&#34;&gt;
&lt;ol&gt;
    &lt;li class=&#34;footnote&#34; id=&#34;fn:1&#34;&gt;
        &lt;p&gt;
        You can see that on &lt;a href=&#34;https://www.google.com/trends/explore#q=jQuery%2C%20backbone%2C%20Angular%2C%20Ember%2C%20React&amp;date=1%2F2010%2065m&amp;cmpt=q&amp;tz=&#34;&gt;Google Trends&lt;/a&gt;, &lt;a href=&#34;http://bower.io/stats/&#34;&gt;Bower stats&lt;/a&gt;, or &lt;a href=&#34;https://github.com/jquery/jquery&#34;&gt;Github stars&lt;/a&gt;
        &lt;/p&gt;
        &lt;a href=&#34;#fnref:1&#34; title=&#34;return to article&#34;&gt;↩&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li class=&#34;footnote&#34; id=&#34;fn:2&#34;&gt;
        &lt;p&gt;
        jQuery&#39;s build process is actually super intersting, as they allow custom builds that optionally exclude portions of the library.  If you get a chance make sure to look through build.js and note the function to remove requireJS boilerplate after the modules have been built.
        &lt;/p&gt;
        &lt;a href=&#34;#fnref:2&#34; title=&#34;return to article&#34;&gt;↩&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
        &lt;li class=&#34;footnote&#34; id=&#34;fn:3&#34;&gt;
            &lt;p&gt;
            If you&#39;re unclear on how constructors and prototypes work in JavaScript, feel free to catch up with &lt;a href=&#34;http://benmccormick.org/2013/01/12/explaining-javascript-object-oriented-programming&#34;&gt;this post&lt;/a&gt; I wrote on Object Oriented Programming in JavaScript a few years back.
            &lt;/p&gt;
            &lt;a href=&#34;#fnref:3&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
        &lt;/li&gt;
            &lt;li class=&#34;footnote&#34; id=&#34;fn:4&#34;&gt;
                &lt;p&gt;
                Ok so we didn&#39;t have quite enough information to fully understand this yet, but you can see where the init function gets its prototye &lt;a href=&#34;https://github.com/jquery/jquery/blob/master/src/core/init.js#L115&#34;&gt;here&lt;/a&gt;.
                &lt;/p&gt;
                &lt;a href=&#34;#fnref:4&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
            &lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Moving Past RequireJS</title>
      <link>https://benmccormick.org/2015/05/28/091000.html</link>
      <pubDate>Thu, 28 May 2015 10:10:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2015/05/28/091000.html</guid>
      <description>&lt;p&gt;RequireJS has been a hugely influential and important tool in the JavaScript world.  It&amp;rsquo;s still used in many solid, well-written projects today.  But as it has stagnated and competitors have grown up, it now suffers compared to the alternatives.  It&amp;rsquo;s time for new projects to look past RequireJS when deciding how to structure their front-end projects.&lt;/p&gt;
&lt;h3 id=&#34;what-is-requirejs&#34;&gt;What is RequireJS?&lt;/h3&gt;
&lt;p&gt;RequireJS is the most well known module loader for JavaScript.  Module loaders are tools for specifying dependencies for JavaScript files and loading those files into a browser.  They became necessary because JavaScript has not traditionally offered a built in way to specify what other code is needed to execute a file.  Developers coming from server side languages like Java and Python are used to being able to import anything they need from another file, letting the language handle the details.  Since that was not designed into JavaScript, the only alternative originally was having developers take care that all scripts were correctly loaded into a page together in the right order, then making references across files without the assurance that the other file existed.&lt;/p&gt;
&lt;p&gt;Module loaders improve on that by allowing you to define dependencies for your JavaScript files, and assuring that those dependencies are loaded in the correct order so that the variables the code needs are there when referenced.  These dependencies are specified using one of several &amp;ldquo;module formats&amp;rdquo;.  There are currently 3 primary competing standards for JavaScript modules: AMD or Asynchronous Module Definition, CommonJS, and EcmaScript 6 Modules.  I&amp;rsquo;ll discuss these more below, but each of them provide syntax for listing the files that a module requires as a dependency, and the object that the module wishes to import from those files.&lt;/p&gt;
&lt;h3 id=&#34;why-not-start-a-project-with-requirejs&#34;&gt;Why not start a project with RequireJS?&lt;/h3&gt;
&lt;p&gt;RequireJS was the first JavaScript module loader to gain widespread popularity.  It&amp;rsquo;s used in hundreds of successful production sites, and is widely referenced in JavaScript books, blog posts, and talks.  I personally led a project to convert a large web application to use it for dependency management in my previous job, and still use it now in a current project.  So why would I say not to use it for your project?  There are two sets of issues with RequireJS:  issues with the AMD module format, and increased competition in terms of the features expected from a module loader.&lt;/p&gt;
&lt;h3 id=&#34;the-problems-with-amd&#34;&gt;The problems with AMD&lt;/h3&gt;
&lt;p&gt;RequireJS requires developers to use AMD modules.  That choice made a ton of sense in 2011 when RequireJS first launched.  It makes less sense today.  In 2011, the only popular alternative to AMD modules was the CommonJS standard, and AMD held a technical advantage over CommonJS. It was essentially a decision between a technological superiority and a cleaner API. In 2015, AMD is one of 3 realistic module syntax alternatives, and no longer holds a significant technical advantage, but it still has a less clear syntax and has begun to experience problems with network effects.&lt;/p&gt;
&lt;h4 id=&#34;syntax-comparison&#34;&gt;Syntax Comparison&lt;/h4&gt;
&lt;p&gt;AMD modules look like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;define([&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;file1&amp;#39;&lt;/span&gt;,&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;file2&amp;#39;&lt;/span&gt;], &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(Class1, Class2) {
    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; obj &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; Class1(),
        obj2 &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; Class2();
    &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; obj.foo(obj2);
});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A &lt;code&gt;define&lt;/code&gt; function is used to define a new module.  It takes 2 arguments: an array of dependencies (specified as strings), and a callback function that is passed in the values exported by each dependency and run after all of the dependencies have been loaded.  AMD also provides a require function that takes the same arguments, but serves as the initialization point of a program, loading its dependencies and executing them when it&amp;rsquo;s run.&lt;/p&gt;
&lt;p&gt;Compare that to CommonJS and the ES6 Modules syntax:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;//commonJS
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; Class1 &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; require(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;file1&amp;#39;&lt;/span&gt;),
    Class2 &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; require(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;file2&amp;#39;&lt;/span&gt;),
    obj &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; newClass1(),
    obj2 &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; Class2();

module.exports &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; obj.foo(obj2);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;//ES6
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; Class1 from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;file1&amp;#39;&lt;/span&gt;;
&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; Class2 from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;file2&amp;#39;&lt;/span&gt;;

&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; obj &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; newClass1(),
    obj2 &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; Class2();

&lt;span style=&#34;color:#ff79c6&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;default&lt;/span&gt; obj.foo(obj2);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;There&amp;rsquo;s some obvious niceties there.  CommonJS and ES6 modules don&amp;rsquo;t require you to wrap your code in an outer function, which serves to reduce boilerplate and also aligns the import code more closely with the expectations of developers who have used imports in server-side languages.&lt;/p&gt;
&lt;p&gt;But there are also other subtler problems with the AMD syntax.  Because you&amp;rsquo;re asked to specify your dependencies as an array of strings that then result in parameters to a callback function, adding or removing a dependency requires code to be changed in 2 places. &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;  This is no big deal in a simple example like above.  But what about in this real world example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;define([&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;marionette&amp;#39;&lt;/span&gt;,
        &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;radio&amp;#39;&lt;/span&gt;,
        &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;underscore&amp;#39;&lt;/span&gt;,
        &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;lib/analytics&amp;#39;&lt;/span&gt;,
        &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;collections/widget&amp;#39;&lt;/span&gt;,
        &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;collections/user&amp;#39;&lt;/span&gt;,
        &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;models/user&amp;#39;&lt;/span&gt;,
         &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;routers/widget_page_router&amp;#39;&lt;/span&gt;,
        &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;views/widget_page/page&amp;#39;&lt;/span&gt;],

&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(Mn, Radio, _, Analytics, WidgetCollection, UsersCollection,
    User, WidgetRouter, WidgetPage) {
        &lt;span style=&#34;color:#6272a4&#34;&gt;//module code here
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If you were asked to remove a dependency here, it&amp;rsquo;s easy to imagine accidentally putting a parameter in the wrong position in the list, or removing an item from one list without the other, causing the parameters to be set to the wrong values.  It&amp;rsquo;s a small issue, but the type of subtle source of bugs that can drive developers crazy.&lt;/p&gt;
&lt;p&gt;Finally the mixed use of require and define for pulling in dependencies seems to be confusing to many developers.  While it certainly isn&amp;rsquo;t a large learning curve (require is for initiating new code, define is for defining a module that can be pulled into a dependency tree started by a require), it&amp;rsquo;s an additional point of confusion that doesn&amp;rsquo;t exist in CommonJS, which simply has a &amp;ldquo;starting script&amp;rdquo; that is run and pulls in its dependencies.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;: &lt;em&gt;Commenters on Reddit have correctly pointed out that there&amp;rsquo;s a &lt;a href=&#34;http://requirejs.org/docs/whyamd.html#sugar&#34;&gt;second usable AMD syntax&lt;/a&gt; that cleans up some of these issues.  I didn&amp;rsquo;t include it originally since it&amp;rsquo;s not the &amp;ldquo;official&amp;rdquo; AMD syntax and I have not seen it widely used, but it is better and worth noting for users sticking with RequireJS/AMD&lt;/em&gt;&lt;/p&gt;
&lt;h4 id=&#34;technical-advantages&#34;&gt;Technical Advantages&lt;/h4&gt;
&lt;p&gt;When RequireJS was first created, AMD had a few technical advantages over CommonJS solutions.  AMD was set up to be asynchronous.  The callback function syntax made it easy to handle dependency loading over a network.  You made the define call, loaded the dependencies, and once all of the dependencies had been pulled over the network, ran the callback function.  This also allowed some dependencies to be lazy-loaded after the initial page load, since that could be handled like any other ajax request with a callback attached.  Since CommonJS was set up in a more synchronous fashion, it was less clear how to accomplish this, and early systems were less popular than requireJS.&lt;/p&gt;
&lt;p&gt;AMD&amp;rsquo;s asynchronous nature remains a theoretical advantage, but in practice, modern module loaders have found ways to solve these problems for CommonJS.  Webpack allows configuration options for lazy loading individual modules, and developers using Browserify have &lt;a href=&#34;http://esa-matti.suuronen.org/blog/2013/04/15/asynchronous-module-loading-with-browserify/&#34;&gt;found workarounds&lt;/a&gt; to the problem.  At this point there&amp;rsquo;s no real difference in the capabilities of AMD compared to other module formats.&lt;/p&gt;
&lt;h4 id=&#34;network-effects&#34;&gt;Network Effects&lt;/h4&gt;
&lt;p&gt;While RequireJS and AMD were initially the most popular module system for the browser, CommonJS is built into Node.js and has always been the dominant module format on the server-side.   This was initially no big deal, but Node has grown in popularity and also become more important to client-side developers due to the tooling ecosystem around it.  Because of that, code that doesn&amp;rsquo;t play well with Node is limited in ways that CommonJS  is not.  One area that I&amp;rsquo;ve noticed this is unit testing.  There&amp;rsquo;s a whole ecosystem of unit-testing libraries that allow you to test your modules on the command line using Node (Mocha, jasmine-node, Jest).  This has nice advantages relative to running your tests in a browser.  It&amp;rsquo;s easy to integrate into a build workflow, the test framework can run all tests in a directory without developers needing to manually add them to a test page, and there&amp;rsquo;s no extra browser window required.  With AMD you can get part of the way there by making all of your tests asynchronous (painful) and importing requireJS or by using PhantomJS to run your browser tests on the command-line.  But you can&amp;rsquo;t match the experience of full node compatibility.&lt;/p&gt;
&lt;p&gt;In addition to the unit test example, there are many small node modules out there that can be usefully pulled into a web project.  Libraries like Ampersand.js and Event-Emitter are quite useful in a browser context, but only play nicely if you&amp;rsquo;re using CommonJS.  While it&amp;rsquo;s true that most libraries do support AMD, they tend to do so through a &amp;ldquo;Universal&amp;rdquo; module format that checks the environment to see what module format is being used and then uses appropriate format.  I&amp;rsquo;m unfamiliar with any examples of major JavaScript libraries that support AMD module loaders but not CommonJS.  So choosing AMD limits you in a way that choosing CommonJS does not.&lt;/p&gt;
&lt;p&gt;This is not a disadvantage that&amp;rsquo;s likely to get fixed for AMD modules anytime soon.  If these network effects shift at all, they&amp;rsquo;re only likely to do so in favor of ES6 modules, which have the appeal of being a &amp;ldquo;blessed&amp;rdquo; part of the JavaScript language. So in the short and long term, it&amp;rsquo;s fair to expect that using AMD modules will limit your compatibility with other tools and libraries compared to CommonJS.&lt;/p&gt;
&lt;h3 id=&#34;what-are-the-alternatives-to-requirejs&#34;&gt;What are the alternatives to RequireJS?&lt;/h3&gt;
&lt;p&gt;In 2015, RequireJS is one of 3 major options on the module loading scene, along with &lt;a href=&#34;http://browserify.org/&#34;&gt;Browserify&lt;/a&gt; and &lt;a href=&#34;http://webpack.github.io/&#34;&gt;Webpack&lt;/a&gt;.  Browserify is an attempt to build a module loader on top of the NPM ecosystem and node modules.  It uses CommonJS modules and integrates tightly with NPM.  Webpack is an attempt to unify the modules landscape by supporting AMD, CommonJS and ES6 modules.  It handles JavaScript, CSS and other assets, as well as preprocessors for each. RequireJS suffers in comparison to both of them, both in terms of features and workflow.&lt;/p&gt;
&lt;p&gt;Browserify and Webpack both provide servers for development, allowing you to instantly integrate changes without a long build process or extra JavaScript files loaded into the browser. RequireJS doesn&amp;rsquo;t have a great solution for development workflow, requiring you to either do a full build every time, or load a copy of the require.js JavaScript file up to your browser where it loads files from the client.  This has disadvantages both in terms of reliability (you&amp;rsquo;ll be running the files in a different way in development than on production, and there will be timing differences due to the need to load the files on the client), and configuration (you&amp;rsquo;ll need to have separate configurations for development and production that will have to be kept in sync somehow).&lt;/p&gt;
&lt;p&gt;Browserify and Webpack also provide a clean syntax for preprocessing things like CoffeeScript or JSX files, using transforms or loaders (respectively).  These transforms can be applied to a subset of files with configuration. These methods compare favorably to RequireJS&amp;rsquo;s plugin system, which require you to manually specify the plugins used each time you load a resource.&lt;/p&gt;
&lt;p&gt;All of this adds up to a strong case for not starting new projects with RequireJS.  It&amp;rsquo;s a good tool that has benefited many projects, but as other people have learned from its pain points and provided superior solutions, the time has come to move on.&lt;/p&gt;
&lt;h3 id=&#34;disclaimers&#34;&gt;Disclaimers&lt;/h3&gt;
&lt;p&gt;It should be noted here that this article is addressed primarily at developers starting new projects.  If you&amp;rsquo;re working on an project that already uses RequireJS, you&amp;rsquo;ve probably already worked through the configuration pain, gotten used to the syntax, found a compatible unit testing library and developed a strategy for live development.  If these aren&amp;rsquo;t things that are causing you pain, don&amp;rsquo;t switch.  RequireJS is a stable tool that has stood the test of time.  It&amp;rsquo;s not inherently flawed.  There are simply better options out there these days for developers starting new projects.&lt;/p&gt;
&lt;h3 id=&#34;more-resources&#34;&gt;More Resources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Axel Rauschmayer has a &lt;a href=&#34;http://www.2ality.com/2014/09/es6-modules-final.html&#34;&gt;great piece&lt;/a&gt; up on his blog 2ality describing ECMAScript 6 modules and how they compare to CommonJS&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;This &lt;a href=&#34;https://blog.andyet.com/2014/06/25/introducing-ampersand-js&#34;&gt;blog post&lt;/a&gt; is primarily an introduction post for Ampersand.js, a modular JS framework. But it also serves as a great look at the environment around nodejs and CommonJS modules, including a discussion of the advantages and disadvantages of using many small modules to structure applications.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Several users on &lt;a href=&#34;http://www.reddit.com/r/javascript/comments/37lowt/moving_past_requirejs/&#34;&gt;reddit&lt;/a&gt;, have pointed out that &lt;a href=&#34;https://github.com/systemjs/systemjs&#34;&gt;systemjs&lt;/a&gt; is another competing module loader worth discussing.  I didn&amp;rsquo;t include it because it&amp;rsquo;s less mature and wouldn&amp;rsquo;t be something I&amp;rsquo;d currently recommend for production apps, but it looks to be getting there quickly and is certainly another option to consider.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;footnotes&#34;&gt;
&lt;ol&gt;
    &lt;li class=&#34;footnote&#34; id=&#34;fn:1&#34;&gt;
        &lt;p&gt;
        AMD does allow you to use an alternative syntax that is more similar to CommonJS that avoids this issue with &#34;off by 1&#34; errors.  But since it&#39;s an alternative syntax, not the recommended one, I think it&#39;s fair to critique this as an issue.  My other points apply equally to both forms.
        &lt;a href=&#34;#fnref:1&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>marionette-service: Service Objects for Marionette</title>
      <link>https://benmccormick.org/2015/05/25/090200.html</link>
      <pubDate>Mon, 25 May 2015 10:02:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2015/05/25/090200.html</guid>
      <description>&lt;p&gt;&lt;a href=&#34;http://backbonejs.org/&#34;&gt;Backbone.js&lt;/a&gt; is a great way to structure web applications.  Its built in Models, Collections, Views and Routers are a very reasonable &amp;ldquo;minimum common ground&amp;rdquo; that pretty much any web project will be able to put to good use.  But more sophisticated applications have needs that extend beyond these basic concepts.  In addition to having some data that needs to be displayed, rich web apps often have resources and functionality that need to be shared across many different Views and Models.  There&amp;rsquo;s no definitive way to implement this consistently, but a common pattern is to create &amp;ldquo;services&amp;rdquo; of some type that Views and Models can communicate with.&lt;/p&gt;
&lt;p&gt;This pattern is easiest to show with an example.  Let&amp;rsquo;s take a look at a simple logging implementation.  We might start out just using simple console commands throughout our code like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt; doFoo() {
  &lt;span style=&#34;color:#6272a4&#34;&gt;// Do a thing
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;  console.log(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;We did Foo&amp;#39;&lt;/span&gt;);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That&amp;rsquo;s fine for a while, but what if we wanted to switch to a logging library like &lt;a href=&#34;http://js.jsnlog.com/&#34;&gt;JSNLog&lt;/a&gt; or some 3rd party service?  We&amp;rsquo;d have a huge find and replace job to work through.  It&amp;rsquo;s better to centralize.  &lt;a href=&#34;https://github.com/marionettejs/backbone.radio&#34;&gt;Backbone.Radio&lt;/a&gt; is perfect for this purpose.  We can use it to centralize our logic and create a logging module:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;*&lt;/span&gt; as Radio from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;backbone.radio&amp;#39;&lt;/span&gt;

&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; loggingChannel &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; Radio.channel(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;log&amp;#39;&lt;/span&gt;);

loggingChannel.comply(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;log&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(message) {
    console.log(message);
});

loggingChannel.comply(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;logError&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(message) {
    console.error(message);
});

loggingChannel.comply(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;logWarning&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(message) {
    console.warn(message);
});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We could then log a message like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt; doFoo() {
  &lt;span style=&#34;color:#6272a4&#34;&gt;// Do a thing
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;  loggingChannel.command(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;log&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;We did Foo&amp;#39;&lt;/span&gt;);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;There are 2 main use cases for this sort of service pattern: centralizing common tasks and UI actions like logging or displaying an alert, and requesting a resource without having to worry about where it came from.  Both are easily possible using Backbone Radio, using code very similar to whats above.&lt;/p&gt;
&lt;p&gt;Using Backbone Radio like this is a useful pattern, but it&amp;rsquo;s very ad hoc and imperative.  Not very Backbone-like.  What if we could follow the Marionette route of pulling a useful pattern into an object and allow it to be configured declaratively?  We could instead create a &amp;ldquo;Service Object&amp;rdquo; like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;*&lt;/span&gt; as Mn from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;backbone.marionette&amp;#39;&lt;/span&gt;

&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; LoggingService &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; Mn.Service.extend({

    radioCommands&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; {
        &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;log log&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;logMessage&amp;#39;&lt;/span&gt;,
        &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;log logError&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;logError&amp;#39;&lt;/span&gt;,
        &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;log logWarning&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;logWarning&amp;#39;&lt;/span&gt;,
    },

    logMessage&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(message) {
        console.log(message);
    },

    logError&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(message) {
        console.error(message);
    },

    logWarning&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(message) {
        console.warn(message);
    },
});

&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;let&lt;/span&gt; logger &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; LoggingService();
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is much more in the Backbone and Marionette style, with a declarative hash to delegate to different functions based on channels and the events passed.  It makes it much easier to create &amp;ldquo;service objects&amp;rdquo; to make functionality available in a decoupled way.&lt;/p&gt;
&lt;p&gt;Declarative radio handling will be &lt;a href=&#34;https://github.com/marionettejs/backbone.marionette/pull/2431&#34;&gt;coming to Marionette Core&lt;/a&gt; as part of Marionette version 3, but for now I&amp;rsquo;ve written a small library to make it available in the short term.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/benmccormick/marionette-service&#34;&gt;marionette-service&lt;/a&gt; provides the above Service Object to Marionette.  It allows you to listen to Radio Events, Commands or Requests, and associate them with callback functions.  It&amp;rsquo;s compatible with plans for Marionette v3, so all that will be required to remove it when upgrading will be a name change for service objects to use Marionette.Object rather than Marionette.Service. I&amp;rsquo;m excited to see how people use it.&lt;/p&gt;
&lt;p&gt;Marionette-service is available to install both on &lt;a href=&#34;https://www.npmjs.com/package/marionette-service&#34;&gt;npm&lt;/a&gt;, and &lt;a href=&#34;http://bower.io/search/?q=marionette%20service&#34;&gt;bower&lt;/a&gt;.  Or you can clone the repo directly from &lt;a href=&#34;https://github.com/benmccormick/marionette-service&#34;&gt;Github&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;more-resources&#34;&gt;More Resources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;If you&amp;rsquo;re new to Backbone.Radio you can learn more about it from &lt;a href=&#34;http://benmccormick.org/2015/01/26/backbone-radio/&#34;&gt;my post&lt;/a&gt;, or from the &lt;a href=&#34;https://github.com/marionettejs/backbone.radio&#34;&gt;official docs&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;If you&amp;rsquo;re confused why somebody would want to separate out the implementation of a service through Radio rather than passing a service object directly, &lt;a href=&#34;http://arguments.callee.info/2009/05/18/javascript-design-patterns--mediator/&#34;&gt;this is a nice piece by HB Stone&lt;/a&gt; on the power of loose coupling and the Mediator Pattern&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Why Backbone.js and ES6 Classes Don&#39;t Mix</title>
      <link>https://benmccormick.org/2015/04/06/221944.html</link>
      <pubDate>Mon, 06 Apr 2015 23:19:44 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2015/04/07/221944.html</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve seen some confusion out there about how to use ES6 Classes with &lt;a href=&#34;http://backbonejs.org/&#34;&gt;Backbone&lt;/a&gt;.  In the original version of the ES6 class spec, this was actually a simple thing to do, though the syntax wasn&amp;rsquo;t great.  With the finalized specification for classes and subclassing though, it&amp;rsquo;s no longer practical to try and use the two together.  Here&amp;rsquo;s a short explanation of the issues, as well as a discussion on whether any of this matters.&lt;/p&gt;
&lt;h3 id=&#34;what-are-es6-classes-anyway&#34;&gt;What are ES6 Classes anyway?&lt;/h3&gt;
&lt;p&gt;ES6 &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; is the newest version of JavaScript. It provides a variety of new features for JavaScript developers including native Promises, destructuring, modules and default function parameters.  One of these new features is a native JavaScript Class implementation.  It allows us to simplify class patterns that were formerly a bit verbose in JavaScript.  Take this example of JavaScript inheritance from &lt;a href=&#34;http://www.amazon.com/gp/product/0596517742/ref=as_li_tl?ie=UTF8&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=0596517742&amp;amp;linkCode=as2&amp;amp;tag=benmccormicko-20&amp;amp;linkId=XZEWUV7PCEO7DNTY&#34;&gt;Javascript: The Good Parts&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; Mammal &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt; (name) {
    &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.name &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; name;
};

Mammal.prototype.get_name &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt; () {
    &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.name;
};

Mammal.prototype.says &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt; () {
    &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.saying &lt;span style=&#34;color:#ff79c6&#34;&gt;||&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;;
};

&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; Cat &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt; (name) {
    &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.name &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; name;
    &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.saying &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;meow&amp;#39;&lt;/span&gt;;
}

Cat.prototype &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; Mammal();

Cat.prototype.purr &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt; (n) {
    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; i, s &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;;
    &lt;span style=&#34;color:#ff79c6&#34;&gt;for&lt;/span&gt; (i &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;0&lt;/span&gt;; i &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt; n; i &lt;span style=&#34;color:#ff79c6&#34;&gt;+=&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;) {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (s) {
            s &lt;span style=&#34;color:#ff79c6&#34;&gt;+=&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;-&amp;#39;&lt;/span&gt;;
        }
        s &lt;span style=&#34;color:#ff79c6&#34;&gt;+=&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;r&amp;#39;&lt;/span&gt;;
    }
    &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; s;
};

Cat.prototype.get_name &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt; () {
    &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.says() &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39; &amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.name &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39; &amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.says();
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It&amp;rsquo;s a bit verbose.  With ES6 classes we can instead write:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; Mammal {
    constructor() {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.name &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; name;
    }

    get_name() {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.name;
    }

    says() {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.saying &lt;span style=&#34;color:#ff79c6&#34;&gt;||&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;;
    }
}

&lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; Cat &lt;span style=&#34;color:#ff79c6&#34;&gt;extends&lt;/span&gt; Mammal {
    constructor() {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;super&lt;/span&gt;();
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.saying &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;meow&amp;#39;&lt;/span&gt;;
    }

    purr(n) {
        &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; i, s &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;;
        &lt;span style=&#34;color:#ff79c6&#34;&gt;for&lt;/span&gt; (i &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;0&lt;/span&gt;; i &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt; n; i &lt;span style=&#34;color:#ff79c6&#34;&gt;+=&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;) {
            &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (s) {
                s &lt;span style=&#34;color:#ff79c6&#34;&gt;+=&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;-&amp;#39;&lt;/span&gt;;
            }
            s &lt;span style=&#34;color:#ff79c6&#34;&gt;+=&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;r&amp;#39;&lt;/span&gt;;
        }
        &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; s;
    }

    get_name() {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.says() &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39; &amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.name &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39; &amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.says();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This allows us to clean things up a lot, removing some boilerplate and focusing the code on our intended functionality.  ES6 classes work quite nicely for simple JavaScript classes like that.  But what about Backbone objects like Models and Views?&lt;/p&gt;
&lt;p&gt;We might think that we can just treat them as classes and the new syntax will &amp;ldquo;just work&amp;rdquo;, similar to how CoffeeScript classes function.  So we&amp;rsquo;d take this example from the &lt;a href=&#34;http://backbonejs.org/&#34;&gt;Backbone website&lt;/a&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; DocumentRow &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; Backbone.View.extend({

  tagName&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;li&amp;#34;&lt;/span&gt;,

  className&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;document-row&amp;#34;&lt;/span&gt;,

  events&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; {
    &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;click .icon&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;          &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;open&amp;#34;&lt;/span&gt;,
    &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;click .button.edit&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;   &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;openEditDialog&amp;#34;&lt;/span&gt;,
    &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;click .button.delete&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;destroy&amp;#34;&lt;/span&gt;
  },

  initialize&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;() {
    &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.listenTo(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.model, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;change&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.render);
  },

  render&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;() {
    &lt;span style=&#34;color:#6272a4&#34;&gt;//...
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;  }

});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;and convert it to something like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; DocumentRow &lt;span style=&#34;color:#ff79c6&#34;&gt;extends&lt;/span&gt; Backbone.View {

  tagName&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;li&amp;#34;&lt;/span&gt;

  className&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;document-row&amp;#34;&lt;/span&gt;

  events&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; {
    &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;click .icon&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;          &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;open&amp;#34;&lt;/span&gt;,
    &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;click .button.edit&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;   &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;openEditDialog&amp;#34;&lt;/span&gt;,
    &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;click .button.delete&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;destroy&amp;#34;&lt;/span&gt;
  }

  initialize() {
    &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.listenTo(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.model, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;change&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.render);
  }

  render() {
    &lt;span style=&#34;color:#6272a4&#34;&gt;//...
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Unfortunately this errors out.  So what&amp;rsquo;s the problem?  It turns out that ES6 classes don&amp;rsquo;t support adding properties directly to the class instance, only functions/methods.  This makes sense when you understand what is actually happening.  With JavaScript inheritance, properties are generally meant to be set on an instance when its created, while methods are set on the prototype object and shared between every instance.  If properties are added to the prototype directly they will also get shared between every instance, creating problems if the property is an object with mutable state like an array.  You can see that in the following simple example:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;var testClass = function(){};
testClass.prototype.foo = [];

var testA = new testClass();
var testB = new testClass();

console.log(testA.foo.length); //0
console.log(testB.foo.length); //0
testA.foo.push(&#39;x&#39;);
console.log(testA.foo.length); //1
console.log(testB.foo.length); //1
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;When we place a property on the prototype it can cause unexpected side effects.  Instead most of the time, we want to use the class&#39; constructor to add any properties to each new instance.  &lt;del&gt;Since that is a bit unwieldy when adding many properties, Backbone abstracts away this difference with its extend function.&lt;/del&gt; &lt;strong&gt;Edit: Backbone actually does add properties directly to the prototype, going against conventions a bit.&lt;/strong&gt; But ES6 classes are focused on the prototype, and the code that is shared between instances. They make the opinionated default properties for instances are handled in the constructor. This maps very cleanly to the current semantics for existing JavaScript class creation, but is different than Backbone&amp;rsquo;s abstraction. So using ES6 classes for Backbone, we&amp;rsquo;ll need to give up this nicety.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; DocumentRow &lt;span style=&#34;color:#ff79c6&#34;&gt;extends&lt;/span&gt; Backbone.View {

    constructor() {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.tagName &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;  &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;li&amp;#34;&lt;/span&gt;;
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.className &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;document-row&amp;#34;&lt;/span&gt;;
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.events &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {
            &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;click .icon&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;          &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;open&amp;#34;&lt;/span&gt;,
            &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;click .button.edit&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;   &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;openEditDialog&amp;#34;&lt;/span&gt;,
            &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;click .button.delete&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;destroy&amp;#34;&lt;/span&gt;
        };
        &lt;span style=&#34;color:#ff79c6&#34;&gt;super&lt;/span&gt;();
    }

    initialize() {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.listenTo(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.model, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;change&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.render);
    }

    render() {
        &lt;span style=&#34;color:#6272a4&#34;&gt;//...
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Until recently, this was a valid way of defining a Backbone View with ES6 classes.  It&amp;rsquo;s questionable whether it was a real gain, given the relative ugliness of the syntax for defining instance properties, but it did work.   Unfortunately, in the final version of the ES6 spec for classes, this is no longer valid.  The final spec requires &lt;code&gt;super()&lt;/code&gt; to be called before &lt;code&gt;this&lt;/code&gt; is referenced in a constructor for classes that are extending another class.  So we have to change our constructor to look like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; DocumentRow &lt;span style=&#34;color:#ff79c6&#34;&gt;extends&lt;/span&gt; Backbone.View {

    constructor() {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;super&lt;/span&gt;();
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.tagName &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;  &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;li&amp;#34;&lt;/span&gt;;
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.className &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;document-row&amp;#34;&lt;/span&gt;;
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.events &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {
            &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;click .icon&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;          &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;open&amp;#34;&lt;/span&gt;,
            &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;click .button.edit&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;   &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;openEditDialog&amp;#34;&lt;/span&gt;,
            &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;click .button.delete&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;destroy&amp;#34;&lt;/span&gt;
        };
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Unfortunately this doesn&amp;rsquo;t do what we expect. Backbone does significant initialization processing in its constructor, and most properties that Backbone expects to be defined on a Model or View need to be pulled in prior to the constructor executing in order to be used properly.  So with the final ES6 spec we no longer have any way of using declarative properties on subclasses if we want them to be processed by the constructor.&lt;/p&gt;
&lt;h3 id=&#34;so-what-are-our-options&#34;&gt;So what are our options?&lt;/h3&gt;
&lt;p&gt;There are a few workarounds here, but they&amp;rsquo;re ugly.  First, Backbone allows any of of its instance properties to also be defined as methods.  So we can rewrite our View like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; DocumentRow &lt;span style=&#34;color:#ff79c6&#34;&gt;extends&lt;/span&gt; Backbone.View {

    tagName() { &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;li&amp;#34;&lt;/span&gt;; }

    className() { &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;document-row&amp;#34;&lt;/span&gt;;}

    events() {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; {
            &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;click .icon&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;          &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;open&amp;#34;&lt;/span&gt;,
            &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;click .button.edit&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;   &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;openEditDialog&amp;#34;&lt;/span&gt;,
            &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;click .button.delete&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;destroy&amp;#34;&lt;/span&gt;
        };
    }

    initialize() {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.listenTo(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.model, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;change&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.render);
    }

    render() {
        &lt;span style=&#34;color:#6272a4&#34;&gt;//...
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We&amp;rsquo;re starting to get ridiculous here though.  First, this isn&amp;rsquo;t a one to one conversion, so if we&amp;rsquo;re converting existing code, we could develop bugs from any code that directly referenced a View&amp;rsquo;s properties.  And if that code modified those properties, its no longer as simple to modify them again.  Of course if it&amp;rsquo;s a property that isn&amp;rsquo;t processed within the constructor like the &lt;code&gt;url&lt;/code&gt; property for Models, we can simply leave it as is.  But suddenly we&amp;rsquo;re requiring ourselves to know what properties are processed in the constructor or not, as well as wrapping and rewrapping properties in functions.  We&amp;rsquo;ve added a lot of complexity, and it&amp;rsquo;s not totally clear what we&amp;rsquo;ve gained.&lt;/p&gt;
&lt;p&gt;The second option is to simply re-run the Backbone View or Model constructor a second time after adding the initialization properties.  This has a few issues though.  First, it&amp;rsquo;s ugly.  Nobody wants to do this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; DocumentRow &lt;span style=&#34;color:#ff79c6&#34;&gt;extends&lt;/span&gt; Backbone.View {

    constructor() {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;super&lt;/span&gt;();
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.tagName &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;  &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;li&amp;#34;&lt;/span&gt;;
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.className &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;document-row&amp;#34;&lt;/span&gt;;
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.events &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {
            &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;click .icon&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;          &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;open&amp;#34;&lt;/span&gt;,
            &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;click .button.edit&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;   &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;openEditDialog&amp;#34;&lt;/span&gt;,
            &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;click .button.delete&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;destroy&amp;#34;&lt;/span&gt;
        };
        Backbone.View.apply(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;But it also opens an opportunity for more subtle bugs.  Constructors aren&amp;rsquo;t meant to be run twice.  Doing so, will among other things cause the Views initialization function to run twice, with a different &lt;code&gt;cid&lt;/code&gt; (Backbone&amp;rsquo;s internal unique id system) set on the View each time. That violates a ton of expectations, again for no clear gain.  So the long and the short of it is that there&amp;rsquo;s no longer any viable way to use ES6 classes for Backbone objects without a clear loss in functionality and predictability.&lt;/p&gt;
&lt;h3 id=&#34;so-does-any-of-this-matter&#34;&gt;So Does Any Of This Matter?&lt;/h3&gt;
&lt;p&gt;The idea of using ES6 classes for Backbone has some appeal.  The &amp;ldquo;class&amp;rdquo; keyword is nice syntax and there&amp;rsquo;s an appeal to using more standardized code and fewer library extensions.  Right now, many developers are also just curious about ES6 and how it fits into their workflow.  But does it really matter that this doesn&amp;rsquo;t work?  I think a case can be made either way, with 2 clear points in each sides favor.  The case for this being a problem:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;ES6 Classes are becoming the standard&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;By pretty much any standard, Backbone is currently one of the 4 most popular JavaScript frameworks/libraries for building web applications, along with &lt;a href=&#34;https://angular.io/&#34;&gt;Angular&lt;/a&gt;, &lt;a href=&#34;http://emberjs.com/&#34;&gt;Ember&lt;/a&gt;, and &lt;a href=&#34;https://facebook.github.io/react/&#34;&gt;React&lt;/a&gt;.  What do the Angular, Ember, and React teams all have in common?  They&amp;rsquo;re each working to make sure that current or future versions of their frameworks use ES6 classes to define objects.  As this style of code becomes ubiquitous, Backbone will start to look even more boilerplate heavy and non-standard.  Developers will also start learning about ES6 classes as part of standard JavaScript training, requiring them to map their knowledge about prototypes and class syntax to Backbone&amp;rsquo;s concepts, rather than just using things they already understand as in other libraries.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;More Native == Less Library code&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This is more of a far-future advantage, but at some point ES6 classes will be usable everywhere without library support, allowing libraries based on it to include less code for handling this themselves.&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;And the case that it doesn&amp;rsquo;t really matter:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Just because its standardized doesn&amp;rsquo;t make it reusable&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;While it&amp;rsquo;s true that ES6 classes are a standard, realistically Backbone code written using a class syntax isn&amp;rsquo;t going to be easier or harder to convert to equivalent code using React for example.  Backbone&amp;rsquo;s way of using it&amp;rsquo;s standard functions and properties is a much bigger obstacle to code reuse than the particular way it defines classes.  ES6 classes and Backbone objects are in the end just different syntactic sugar over the same prototypical inheritance concepts.  A developer who understands the concepts will be able to use both, and code written in either style will not be easy to reuse outside the Backbone ecosystem.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Sometimes doing it yourself is just better&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The truth is that sometimes there are advantages to writing your own APIs.  Backbone&amp;rsquo;s class code makes the things that are important to using Backbone easy, without any of the trade offs discussed in this article.  There&amp;rsquo;s something to be said for using the right interface for the job.  There are trade offs for this, just as their are trade offs in other libraries choice to require or encourage a build step for their code.  Both these choices improve the developer API at a cost (complexity, extra code, extra process, etc).  Whether those trade offs are worth it is a judgment call.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;It will be interesting to see how the lack of standardization here effects Backbone in the long run, if it does at all.  Along with native Promises, ES6 now offers 2 major features that are similar to but incompatible with important Backbone features &lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;. Along with ES5&amp;rsquo;s get and set capabilities and ES7&amp;rsquo;s Object.Observe &lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;, a significant number of Backbone features that once required library code will someday soon be natively supported. Of course Backbone has never been a set of features as much as a way of writing programs.  Since Backbone is essentially finished and there are &lt;a href=&#34;https://github.com/jashkenas/backbone/issues/3405&#34;&gt;no plans to significantly change the interface&lt;/a&gt;, the continued improvements to the standard language serve as both a validation of Backbone&amp;rsquo;s core concepts as well as a challenge to its future.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; &lt;em&gt;There&amp;rsquo;s been a &lt;a href=&#34;https://github.com/jashkenas/backbone/issues/3560&#34;&gt;great discussion of this issue&lt;/a&gt; on Backbone&amp;rsquo;s Github issue tracker.  Feel free to weigh in there if you&amp;rsquo;re interested in figuring this out.&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&#34;more-resources&#34;&gt;More Resources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;If you do want to use ES6 now, &lt;a href=&#34;https://babeljs.io/&#34;&gt;Babel&lt;/a&gt; is the best tool for making that happen.  The Babel website also contains a &lt;a href=&#34;https://babeljs.io/docs/learn-es6/&#34;&gt;great rundown&lt;/a&gt; of the various features that make up ES6.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Axel Rauschmayer has &lt;a href=&#34;http://www.2ality.com/2015/02/es6-classes-final.html&#34;&gt;a great article&lt;/a&gt; describing the final spec for ES6 classes, including a description of the changes that made them incompatible with Backbone.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;React Developers have noted the same issues with property initializers that Backbone users encounter.  As part of version 0.13 of React, they&amp;rsquo;re supporting a special property initialization syntax for classes, which may eventually be standardized.  There&amp;rsquo;s more info on that in &lt;a href=&#34;https://esdiscuss.org/topic/es7-property-initializers&#34;&gt;this ESDiscuss thread&lt;/a&gt;.  This standard is still being worked out but an experimental support version is available in Babel 5.0.0.  Unfortunately that version defines class properties as being instantiated after the superclass constructor is run, so this doesn&amp;rsquo;t solve Backbone&amp;rsquo;s issues here.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If you were confused by the discussion of prototypes and the code examples of non-ES6 JavaScript classes, I wrote a quick explanation of &lt;a href=&#34;http://benmccormick.org/2013/01/12/explaining-javascript-object-oriented-programming/&#34;&gt;Object Oriented Programming in Javascript&lt;/a&gt; back in 2012.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;footnotes&#34;&gt;
&lt;ol&gt;
    &lt;li class=&#34;footnote&#34; id=&#34;fn:1&#34;&gt;
        &lt;p&gt;
        ECMAScript version 6, now officially ECMAScript 2015
        &lt;a href=&#34;#fnref:1&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
        &lt;li class=&#34;footnote&#34; id=&#34;fn:2&#34;&gt;
            &lt;p&gt;
            This is admittedly a bigger advantage for Ember, Angular 2.0, and React, which all encourage using a build step to convert ES6/Typescript/JSX to ES5 JavaScript.  That means they can all rely on ES6 class support now, since older browser support is handled through compilation.  
            &lt;/p&gt;&lt;p&gt;
            Backbone doesn&#39;t require or encourage a transpilation step (although CoffeeScript works very nicely for this case), and so it&#39;s more important for it to have a top-notch API supported by all JavaScript engines that it is likely to be run on.  It will be a long time before that is true of ES6 classes.
            &lt;a href=&#34;#fnref:2&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
        &lt;/li&gt;
    &lt;li class=&#34;footnote&#34; id=&#34;fn:3&#34;&gt;
        &lt;p&gt;
        Promises are similar to jQuery deferreds, which are technically not a Backbone feature, but are a key part of Backbone development for many developers because they&#39;re used with Backbone sync.
        &lt;a href=&#34;#fnref:3&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Staying DRY with Marionette Behaviors</title>
      <link>https://benmccormick.org/2015/03/22/230417.html</link>
      <pubDate>Mon, 23 Mar 2015 00:04:17 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2015/03/23/230417.html</guid>
      <description>&lt;p&gt;&lt;em&gt;This is the sixth post in a series on &lt;a href=&#34;http://marionettejs.com/&#34;&gt;Marionette.js&lt;/a&gt;.  For more background on what Marionette is, check out the series page, &lt;a href=&#34;http://benmccormick.org/marionette-explained/&#34;&gt;Marionette Explained&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Any successful project draws complaints, and &lt;a href=&#34;http://backbonejs.org/&#34;&gt;Backbone.js&lt;/a&gt; is a successful project by pretty much any measurement.  The biggest complaints I&amp;rsquo;ve heard leveled against Backbone as an MVC framework revolve around the boilerplate involved in writing Backbone apps.  The claim goes that Backbone forces you to write the same event binding and workflow code over and over again.  In general I&amp;rsquo;d claim that&amp;rsquo;s a feature of &lt;em&gt;bad&lt;/em&gt; Backbone apps, and  not something unavoidable.  But it&amp;rsquo;s certainly true that Backbone doesn&amp;rsquo;t give you much guidance on how to reduce repetition and boilerplate in your code.  Making it easy to reduce repetition turns out to be one of the main roles of &lt;a href=&#34;http://marionettejs.com/&#34;&gt;Marionette&lt;/a&gt;. This post is a look at one of the tools that Marionette provides to help you simplify your applications: the Behavior class.&lt;/p&gt;
&lt;p&gt;Marionette Behaviors are reusable chunks of UI logic that you can mix into your Views.  When you have a common problem that you face across several Views, Behaviors can help you reduce boilerplate and repetition.  We&amp;rsquo;ll take a look at a practical example first, and then we can get into the Behaviors API.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s see how Behaviors can help us write better form validation code.  When I&amp;rsquo;m validating forms, I use the &lt;a href=&#34;http://thedersen.com/projects/backbone-validation/&#34;&gt;backbone.validation&lt;/a&gt; library. It provides helpers for checking the validity of model properties and attaching error messages to inputs, but doesn&amp;rsquo;t force a specific workflow. However, I have a specific flow I usually want.  A user should be able to enter data as they see fit to start, with no validation warnings until they&amp;rsquo;ve tried to submit the form.  After they&amp;rsquo;ve initially submitted the form, warnings should appear next to any invalid fields, and they should update and disappear as the user fixes their input.&lt;/p&gt;
&lt;p&gt;That process is pretty easy to implement with backbone.validation.  I simply connect my Model to each form View I create, and in the Model I add some logic to re-validate each time the Model is changed, but only after the first time validation is triggered by a user submit.  That works great in most cases.  The problem comes when I need to re-render my view in the middle of this process.  This is a pretty common occurrence if your form has sub-views that may appear based on the contents of other parts of the form. In that case, I have to make sure that the validation state persists across renders.  That might look something like this. &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;*&lt;/span&gt; as Mn from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;marionette&amp;#39;&lt;/span&gt;;
&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;*&lt;/span&gt; as Validation from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;backbone-validation&amp;#39;&lt;/span&gt;;

&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; FormView &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; Mn.LayoutView.extend({

    template&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;#form&amp;#39;&lt;/span&gt;,

    ui&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; {
        submit&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;.submit&amp;#39;&lt;/span&gt;
    },

    events&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; {
        &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;click @ui.submit&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;submitForm&amp;#39;&lt;/span&gt;
    },

    modelEvents&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; {
        &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;validated&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;setValidated&amp;#39;&lt;/span&gt;,
    },

    onRender&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;() {
        &lt;span style=&#34;color:#6272a4&#34;&gt;//any other post-render View code here
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;
        Validation.bind(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;);
        &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt;(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.validated) {
            &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.model.validate();
        }
    },

    setValidated&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;() {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.validated &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;true&lt;/span&gt;;
    },

    submitForm&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;() {
        &lt;span style=&#34;color:#6272a4&#34;&gt;//handle form submission
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    }

});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So it&amp;rsquo;s not that much code to add the functionality we want.  But when we need this code on multiple Views, adding and maintaining it becomes a pain quickly, creating the type of boilerplate that developers rage against.  So how can Behaviors help? It turns out to be easy to pull the functionality from our example out into a separate Behavior that any View can implement.&lt;/p&gt;
&lt;p&gt;That would look something like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;*&lt;/span&gt; as Mn from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;marionette&amp;#39;&lt;/span&gt;;
&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;*&lt;/span&gt; as Validation from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;backbone-validation&amp;#39;&lt;/span&gt;;

&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; ValidationBehavior &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; Mn.Behavior.extend({

    modelEvents&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; {
        &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;validated&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;setValidated&amp;#39;&lt;/span&gt;,
    },

    onRender&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;() {
        &lt;span style=&#34;color:#6272a4&#34;&gt;//Set up any other form related stuff here
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;        Validation.bind(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.view);
        &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt;(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.hasBeenValidated) {
            &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.view.model.validate();
        }
    },


    setValidated&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;() {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.hasBeenValidated &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;true&lt;/span&gt;;
    },

});

&lt;span style=&#34;color:#ff79c6&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;default&lt;/span&gt; ValidationBehavior;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You could then pull the Behavior back into the View like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;*&lt;/span&gt; as Mn from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;marionette&amp;#39;&lt;/span&gt;;
&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;*&lt;/span&gt; as Validation from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;backbone-validation&amp;#39;&lt;/span&gt;;
&lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;*&lt;/span&gt; as ValidationBehavior from &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;behaviors/validation&amp;#39;&lt;/span&gt;;

&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; FormView &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; Mn.LayoutView.extend({

    template&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;#form&amp;#39;&lt;/span&gt;,

    ui&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; {
        submit&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;.submit&amp;#39;&lt;/span&gt;
    },

    events&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; {
        &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;click @ui.submit&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;submitForm&amp;#39;&lt;/span&gt;
    },

    behaviors&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; {
        validation&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; {
            behaviorClass&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; ValidationBehavior
        }
    },

    submitForm&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;() {
        &lt;span style=&#34;color:#6272a4&#34;&gt;//handle form submission
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    }
});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We could do this for any number of Views that required validation.  The same thing can be done for many other types of functionality, including key-binding and &amp;ldquo;warn before delete&amp;rdquo;.&lt;/p&gt;
&lt;h3 id=&#34;behaviors-api&#34;&gt;Behaviors API&lt;/h3&gt;
&lt;p&gt;Behaviors have essentially the same API as Marionette Views, because they&amp;rsquo;re meant to be extracted out of existing Views.  So the event hashes, ui elements, and life-cycle methods that you find on a Marionette View are all also available on Behaviors.  The life cycle functions on a Behavior execute immediately after their corresponding functions on the Behavior&amp;rsquo;s associated View. Behaviors also get &lt;code&gt;el&lt;/code&gt;, &lt;code&gt;$el&lt;/code&gt; and &lt;code&gt;$&lt;/code&gt; properties that are proxied to the equivalent properties on the Behaviors view.&lt;/p&gt;
&lt;p&gt;Behaviors are not just mixins though. Behavior properties are isolated from the Views they&amp;rsquo;re associated with, preventing naming collisions and also encouraging reusable, decoupled designs.  Generally Behaviors don&amp;rsquo;t directly modify their associated Views or data.  The communication flow is one way, with Behaviors accepting input from their parent View in the form of an options object that is attached to the Behavior when it is created.  You can pass these options through using the behaviors hash on the View.  For instance to pass an error message to the validation behavior above, you could define your behaviors hash like this:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;    behaviors: {
        validation: {
            behaviorClass: ValidationBehavior,
            errorMessage: &#39;You did something wrong.&#39;
        }
    },
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;a-quick-note-on-how-behaviors-attach-to-views&#34;&gt;A quick note on how Behaviors attach to Views&lt;/h3&gt;
&lt;p&gt;You can see in the example above that the general form for attaching Behaviors to a View is to include a key-value pair for each Behavior, where the value is an object that lays out the options for the Behavior.  The interesting thing in the example above is that the name of the key doesn&amp;rsquo;t matter at all.  It&amp;rsquo;s not used by the library in any way; instead Marionette picks out the correct behavior to use based on the behaviorClass property in the value.  So why is the API structured like that?  To understand, you need to know that the Behaviors API supports two separate scenarios for looking up the correct Behaviors for a View.&lt;/p&gt;
&lt;p&gt;The original API Marionette included for looking up Behaviors requires you to override a behaviorsLookup function on Marionette to tell the library where to retrieve your Behaviors from.  The keys of the behaviors hash on a view were passed to the lookup function, which then retrieved the Behavior classes from wherever the user chose to store them (probably a global namespace object).&lt;/p&gt;
&lt;p&gt;That API works great for developers used to using namespaces to organize their code, but for developers using modern JavaScript module loaders, it introduces global state and indirection where it wasn&amp;rsquo;t needed.  To handle this case, the behaviorClass key was added as an option for the value object, allowing developers to specify Behaviors as dependencies of the file they were defining a View in, and then attach the Behavior directly to the View.&lt;/p&gt;
&lt;p&gt;That makes much more sense for module users, but leads to a clunky API where the keys aren&amp;rsquo;t used.  Fortunately, in newer versions of Marionette you can get around this entirely, by defining your behaviors as an array on a view.  So the example above would look like:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;    behaviors: [{
        behaviorClass: ValidationBehavior,
        errorMessage: &#39;You did something wrong.&#39;
    }]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This works due to an undocumented implementation detail in Marionette 2.4.1 &lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;, but will be &lt;a href=&#34;https://github.com/marionettejs/backbone.marionette/pull/2368&#34;&gt;fully supported&lt;/a&gt; in future versions.  In future versions you also will be able to pass a class directly as an array item if the Behavior is not taking any arguments, further cleaning up the API.&lt;/p&gt;
&lt;h3 id=&#34;when-are-behaviors-useful&#34;&gt;When are Behaviors useful?&lt;/h3&gt;
&lt;p&gt;Marionette&amp;rsquo;s documentation explains Behaviors very broadly, which makes sense for official documentation since it gives ideas without limiting how users think about them.  But in my experience Behaviors are best used for three different use-cases.&lt;/p&gt;
&lt;h4 id=&#34;sharing-common-event-handling-logic&#34;&gt;Sharing common event handling logic&lt;/h4&gt;
&lt;p&gt;This is the most obvious use for Behaviors, and what the documentation focuses on.  It&amp;rsquo;s easy to set up common event based UI patterns like &amp;ldquo;warn on close&amp;rdquo; with behaviors.  But they also can be used for more complicated event based UI logic.  At Windsor Circle we use 2 behaviors to share common &amp;ldquo;drag and drop&amp;rdquo; code with a Droppable Behavior that can be implemented by a CollectionView and a Draggable Behavior for ItemViews.  That makes it simple to make any CollectionView based list sortable with drag and drop, and keeps the code in a nice central place where any improvements will be shared across the code base.&lt;/p&gt;
&lt;h4 id=&#34;sharing-common-life-cycle-functions&#34;&gt;Sharing common life-cycle functions&lt;/h4&gt;
&lt;p&gt;In addition to event handling, Behaviors also give you access to the various &lt;a href=&#34;http://benmccormick.org/2015/01/05/marionette-view-life-cycles/&#34;&gt;life cycle&lt;/a&gt; methods of Marionette Views.  That lets you split out common life cycle functionality and reduce code.  An easy example of this would be a Behavior that fades a View in each time by adding a css class with an animation associated with it.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;let FadeIn = Marionette.Behavior.extend({
    onBeforeShow: function() {
        this.$el.addClass(&#39;hidden fadein&#39;);
    },
    onShow: function() {
        this.$el.removeClass(&#39;hidden&#39;);
    }
});
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;which would work with a CSS snippet like this:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;.fadein {
  transition: opacity 1s;  
  opacity: 1;
}

.fadein.hidden {
    opacity: 0;
}
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id=&#34;simplifying-integration-with-libraries&#34;&gt;Simplifying integration with libraries&lt;/h4&gt;
&lt;p&gt;This final use case is a special case of the first 2, but I think its worth mentioning in its own
category.  Many 3rd party Backbone or jQuery libraries require repetitive initialization code to use within a View.  This code is often the same across all Views, or only requires minor tweaks.  The perfect use case for a Behavior!  The Validation code above is one example of this, but it&amp;rsquo;s useful for many plugins.  For instance, if you use the &lt;a href=&#34;http://harvesthq.github.io/chosen/&#34;&gt;Chosen&lt;/a&gt; jQuery plugin to create rich dropdown boxes, you could create a Behavior to automatically initialize select elements with Chosen, and optionally pass a class to restrict it to only initialize selects with a specific class.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;let UseChosen = Marionette.Behavior.extend({
    onRender: function() {
        let className = this.options.className,
            chosenOptions = this.options.chosenOptions || {};
        if(className) {
            this.$(&#39;.${className}&#39;).chosen(chosenOptions);
        }
        else {
            this.$(&#39;select&#39;).chosen(chosenOptions);
        }
    }
});
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id=&#34;wrap-up&#34;&gt;Wrap-Up&lt;/h4&gt;
&lt;p&gt;Behaviors are a great resource for avoiding repetition in your Backbone code.  If you have examples of good open-source Behaviors out there, please mention them in the comments.  I&amp;rsquo;d also love to hear what use cases you&amp;rsquo;ve found for them, even if the code isn&amp;rsquo;t public to share.&lt;/p&gt;
&lt;h3 id=&#34;more-resources&#34;&gt;More Resources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Atomic Object has a &lt;a href=&#34;http://spin.atomicobject.com/2014/09/11/marionette-behaviors-overview/&#34;&gt;nice writeup&lt;/a&gt; on Marionette Behaviors, and a &lt;a href=&#34;http://spin.atomicobject.com/2014/09/12/testing-marionette-js-behaviors/&#34;&gt;followup on testing them&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Behaviors seem to make the most sense to people when given examples of how you might use them.  One great open-source example is this &lt;a href=&#34;https://github.com/behave-ui/behave-ui-hotkeys&#34;&gt;key-binding Behavior&lt;/a&gt; that makes it easy for you to add keyboard shortcuts to a View&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;footnotes&#34;&gt;
&lt;ol&gt;
    &lt;li class=&#34;footnote&#34; id=&#34;fn:1&#34;&gt;
        &lt;p&gt;
        Going forward on this blog I&#39;m planning on using ES6 features in code examples where appropriate.  If the code looks weird to you check out &lt;a href=&#34;https://babeljs.io/docs/learn-es6/&#34;&gt;this nice summary of ES6 features&lt;/a&gt;.    
        &lt;/p&gt;
        &lt;a href=&#34;#fnref:1&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li class=&#34;footnote&#34; id=&#34;fn:2&#34;&gt;
        &lt;p&gt;
        The latest version of Marionette at the time of writing.
        &lt;/p&gt;
        &lt;a href=&#34;#fnref:2&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Guillermo Rauch on ECMAScript 6</title>
      <link>https://benmccormick.org/2015/02/22/163846.html</link>
      <pubDate>Sun, 22 Feb 2015 17:38:46 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2015/02/22/163846.html</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;ECMAScript 6, henceforth ES6 and formerly ES.next, is the latest version of the specification. As of August 2014 no new features are being discussed, but details and edge cases are still being sorted out. It’s expected to be completed and published mid-2015.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Adopting ES6 has simultaneously resulted in increased productivity (by making my code more succinct) and eliminated entire classes of bugs by addressing common JavaScript gotchas.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;More importantly, however, it’s reaffirmed my belief in an evolutionary approach towards language and software design as opposed to clean-slate recreation.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&#34;http://rauchg.com/2015/ecmascript-6/&#34;&gt;http://rauchg.com/2015/ecmascript-6/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A really great look at the highlights of ES6 in practice.  I&amp;rsquo;ve been working heavily with ES6 for the last month or so, and agree with him on the highlights.  The standardized module syntax (which I transpile to AMD modules), Promises and destructuring particularly stand out as useful syntax that produces better code than what I had before.  I also enjoy the &lt;code&gt;=&amp;gt;&lt;/code&gt; syntax, though I wish the language authors hadn&amp;rsquo;t combined a syntactic convenience (shorter syntax) with a semantic difference (fat arrow functions are bound to the current context by default, normal functions are not).&lt;/p&gt;
&lt;p&gt;Also of note is his repeated oblique references to &lt;a href=&#34;https://babeljs.io/&#34;&gt;Babel&lt;/a&gt; (formerly 6to5).  Since I wrote my post on  &lt;a href=&#34;http://benmccormick.org/2014/11/24/alternative-javascript/&#34;&gt;Alternative JavaScript&lt;/a&gt; 2 months ago, Babel has clearly emerged as the best way to use JavaScript features that are not yet widely supported today.  It integrates with a wide variety of tools, is reasonably performant speed-wise, and produces roughly 1-1 output, Coffeescript style.  Highly recommended for anyone looking to get started using or learning about new JavaScript features.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Building Modular Web Apps With Backbone.Radio</title>
      <link>https://benmccormick.org/2015/01/26/070000.html</link>
      <pubDate>Mon, 26 Jan 2015 08:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2015/01/26/070000.html</guid>
      <description>&lt;p&gt;&lt;em&gt;This is the fifth post in a series on &lt;a href=&#34;http://marionettejs.com/&#34;&gt;Marionette.js&lt;/a&gt;.  For more background on what Marionette is, check out the series page, &lt;a href=&#34;http://benmccormick.org/marionette-explained/&#34;&gt;Marionette Explained&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;One of the great things about Backbone is how it encourages a modular approach to building UIs.  Different portions of the pages are separated into individual Views, allowing you to simplify your reasoning about your code by focusing on bite-sized chunks at a time.  Easier said than done though, right?  In practice, it&amp;rsquo;s not hard to create Backbone applications with large views that have tight dependencies on each other.  This usually isn&amp;rsquo;t an intentional decision, but part of a slow decay as developers work to connect the various aspects of their applications.&lt;/p&gt;
&lt;p&gt;So far in this series I&amp;rsquo;ve talked about how Marionette makes it easier to create maintainable Views.  Now I&amp;rsquo;m going to look at &lt;a href=&#34;https://github.com/marionettejs/backbone.radio&#34;&gt;Backbone.Radio&lt;/a&gt;, Marionette&amp;rsquo;s tool for communication between application components.&lt;/p&gt;
&lt;h3 id=&#34;whats-so-hard-about-modular-architecture&#34;&gt;What&amp;rsquo;s so hard about modular architecture?&lt;/h3&gt;
&lt;p&gt;There are many advantages to designing your web UI in a modular or component-based fashion.  Your code tends to be easier to reason about and test, it&amp;rsquo;s easier to swap out one piece of code for another, and it greatly increases the chances that you&amp;rsquo;ll be able to reuse your code in other places.  Unfortunately for all except the most basic applications, different components of a UI always have to be aware of the things that happen in other areas of the UI.  It may be something simple like responding to a button click by showing a modal, or more complicated like updating multiple dashboard items when the user applies a filter, but these connections will exist.  At this point you have options.  You can begin having components reference each other directly for example, or you could try to capture state within a shared data object that each component watches.  But there&amp;rsquo;s another solution that borrows from many years of development best practice on backend systems.  You can use a message bus.&lt;/p&gt;
&lt;h3 id=&#34;a-simple-message-bus&#34;&gt;A simple Message Bus&lt;/h3&gt;
&lt;p&gt;A message bus is a software architecture model for communicating between two systems.  The idea is that instead of referencing each other directly, system components are able to send messages through a shared mediator object.  It&amp;rsquo;s quite straightforward to create a simple message bus using Backbone.&lt;/p&gt;
&lt;p&gt;Backbone.Events is Backbone&amp;rsquo;s event object, which gets mixed into the various Backbone classes to provide the Backbone event functions (&lt;code&gt;on&lt;/code&gt;, &lt;code&gt;off&lt;/code&gt;, &lt;code&gt;listenTo&lt;/code&gt;, &lt;code&gt;trigger&lt;/code&gt;, etc).  It&amp;rsquo;s easy and common to mix it into a separate object.  That&amp;rsquo;s all you need to create a message bus: something like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; mediator &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; _.extend({},Backbone.Events);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now Models and Views can listen to or trigger events on the mediator object, allowing them to communicate without having to be directly aware of each other.  This is a great pattern, and quite useful as is, but there are some limitations.  With a mediator object, all events are global.  Any object can listen to any event, and you have to be careful to avoid naming collisions when using common terms.  It&amp;rsquo;s also a single object for multiple types of communication.&lt;/p&gt;
&lt;h3 id=&#34;the-backboneradio-api&#34;&gt;The Backbone.Radio API&lt;/h3&gt;
&lt;p&gt;Backbone.Radio builds on this concept to provide a more powerful message bus.  Instead of a single object, Radio provides multiple &amp;ldquo;channels&amp;rdquo; each of which can correspond to a page or functional section of your web app. Also, instead of a single events API, Radio provides three, Events, Commands, and Requests, each built for a different use case.&lt;/p&gt;
&lt;h4 id=&#34;events&#34;&gt;Events&lt;/h4&gt;
&lt;p&gt;Radio Events are the exact same as our simple message bus.  When you create a channel with Radio, they extend Backbone.Events.  That means you can call any Backbone.Events function on them, or pass them to the &lt;code&gt;listenTo&lt;/code&gt; method of other Backbone objects.  Events provide Radio&amp;rsquo;s publish-subscribe functionality.  Multiple objects can subscribe to an event using &lt;code&gt;on&lt;/code&gt; or &lt;code&gt;listenTo&lt;/code&gt;.  And any object can publish an event using &lt;code&gt;trigger&lt;/code&gt;.  For those of you unfamiliar with Backbone&amp;rsquo;s events, they have two features that you might not expect.  First, unlike native browser events or jQuery events, Backbone events are synchronous; when you trigger an event, all callbacks that are registered on that event run immediately.  Second, it&amp;rsquo;s easy to pass data with Backbone events.  Unlike native browser events which tend to simply consist of an event and a target, any data you pass when you trigger an event gets passed directly to the callback function, making it a true messaging system.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;events.svg&#34; alt=&#34;events diagram&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Functions Provided&lt;/strong&gt; - &lt;code&gt;on&lt;/code&gt;, &lt;code&gt;off&lt;/code&gt;, &lt;code&gt;trigger&lt;/code&gt;, &lt;code&gt;once&lt;/code&gt;, &lt;code&gt;listenTo&lt;/code&gt;, &lt;code&gt;listenToOnce&lt;/code&gt;, &lt;code&gt;stopListening&lt;/code&gt;&lt;/p&gt;
&lt;h4 id=&#34;commands&#34;&gt;Commands&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Update January 2016&lt;/strong&gt; - &lt;em&gt;During 2015, Commands were deprecated from Backbone.Radio as part of their 1.0.0 release.  From a code level, they&amp;rsquo;re simply a request that doesn&amp;rsquo;t return a value, so feel free to keep any existing code, but change command to request and comply to reply&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Radio Commands are similar to Events, with the distinction that only a single callback can handle or &amp;ldquo;comply&amp;rdquo; to a given command.  Commands do not add any functionality on top of events; instead, they provide a semantic distinction and enforce simpler logic.  When &lt;code&gt;exampleChannel.command(&#39;something&#39;)&lt;/code&gt; is called, you know that it is requesting an action be performed, and you can be confident that there will be no side effects.  Only one object will comply to the command.  Commands are a maintenance-friendly tool; they make your code easier to follow by doing less and doing it more obviously.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;commands.svg&#34; alt=&#34;commands diagram&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Functions Provided&lt;/strong&gt; - &lt;code&gt;comply&lt;/code&gt;, &lt;code&gt;stopComplying&lt;/code&gt;, &lt;code&gt;command&lt;/code&gt;, &lt;code&gt;complyOnce&lt;/code&gt;&lt;/p&gt;
&lt;h4 id=&#34;requests&#34;&gt;Requests&lt;/h4&gt;
&lt;p&gt;Radio Requests share the one-to-one nature of Commands, but provide functionality not seen in Backbone.Events.  You can use Requests to retrieve information from other objects.  Each request can be serviced by a single response callback, with the request receiving the return value of the callback function.  This is very useful for providing resources in a decoupled manner, where a View or other object doesn&amp;rsquo;t have to know the details of how an object is stored or retrieved.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;requests.svg&#34; alt=&#34;requests diagram&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Functions Provided&lt;/strong&gt; - &lt;code&gt;reply&lt;/code&gt;, &lt;code&gt;stopReplying&lt;/code&gt;, &lt;code&gt;request&lt;/code&gt;, &lt;code&gt;replyOnce&lt;/code&gt;&lt;/p&gt;
&lt;h4 id=&#34;channels&#34;&gt;Channels&lt;/h4&gt;
&lt;p&gt;Radio Channels are a method of segmenting out your messaging across functions.  Instead of holding every event inside a global namespace, objects can interact with a Channel that&amp;rsquo;s limited to the functionality they need.  This minimizes the chances of naming collisions across the app, and provides additional semantic guidance for future readers of the code.  It&amp;rsquo;s much easier to trace through small, focused messaging networks than a large, global one when you&amp;rsquo;re trying to understand a complex behavior.&lt;/p&gt;
&lt;h3 id=&#34;backboneradio-in-practice&#34;&gt;Backbone.Radio in practice&lt;/h3&gt;
&lt;p&gt;Radio&amp;rsquo;s API is fairly small and simple.  Its power comes from the development patterns it enables.  The following are examples from my own code of how Radio assists in building modular testable UI code.&lt;/p&gt;
&lt;h4 id=&#34;decouple-your-views-with-radio-events&#34;&gt;Decouple your Views with Radio Events&lt;/h4&gt;
&lt;p&gt;&lt;a href=&#34;http://en.wikipedia.org/wiki/Loose_coupling&#34;&gt;Loose coupling&lt;/a&gt; is one of the most commonly cited design principles in Object Oriented Programming.  In Backbone, loose coupling can be applied to mean that your Views should know as little about each other as possible.  In my own work I implement this by allowing Views to know about and reference their own child Views, but do not allow them to directly reference any other Views.  If Views need to communicate up or across a tree of Views, I use Radio.&lt;/p&gt;
&lt;p&gt;Radio Events are great for alerting other parts of the application about a change of state.  For instance, in an application where we have a main content area and a sidebar that provides context for the main area (for instance, a mail app like Gmail that shows contact info in the sidebar next to an open email), we could use Radio Events to keep our sidebar in sync with the main content.  That might look something like this.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; Mn &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; require(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;backbone.marionette&amp;#39;&lt;/span&gt;);
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; Radio &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; require(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;backbone.radio&amp;#39;&lt;/span&gt;);

&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; inboxChannel &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; Radio.channel(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;inbox&amp;#39;&lt;/span&gt;);

&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; ContactView &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; Mn.ItemView.extend({

    template&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;#contact-template&amp;#39;&lt;/span&gt;,

    initialize&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;() {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.listenTo(inboxChannel, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;show:email&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.showContact);
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.listenTo(inboxChannel, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;show:inbox&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.showAd);
    },

    showContact&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(emailObject) {
        &lt;span style=&#34;color:#6272a4&#34;&gt;//show the contact for the emailObject
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    },

    showAd&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;() {
        &lt;span style=&#34;color:#6272a4&#34;&gt;//when we don&amp;#39;t have a contact to show, show an ad instead
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    }

});

module.exports &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; ContactView;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Note that our sidebar View doesn&amp;rsquo;t need to know anything about the inbox area.  The &lt;code&gt;show:email&lt;/code&gt; event could be fired by our inbox view, by a navigation View, or by our router on page load.  The sidebar doesn&amp;rsquo;t know and doesn&amp;rsquo;t care.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s also important to note that the event represents a change in state external to our component.  Something else changed (the state of the inbox), and the sidebar component is reacting to this.  There might be many coponents that react to this state change, or just this one.  Our View doesn&amp;rsquo;t know or care.&lt;/p&gt;
&lt;h4 id=&#34;centralize-ui-logic-with-commands&#34;&gt;Centralize UI Logic with Commands&lt;/h4&gt;
&lt;p&gt;While Events are a way of notifying other components about a change in state, commands are useful when you want to cause a change in state without having to know the implementation.  For instance, in an application that I work on, we have a centralized event-logging module that can take application events that we want logged and send them to a backend API and also to Google Analytics.  We use commands for this.  In practice the logging module looks a bit like this.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; Radio &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; require(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;backbone.radio&amp;#39;&lt;/span&gt;);

&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt; log(event) {
    &lt;span style=&#34;color:#6272a4&#34;&gt;// Send event to the backend API and Google Analytics
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;}

Radio.channel(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;appEvents&amp;#39;&lt;/span&gt;).comply(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;log&amp;#39;&lt;/span&gt;,log);

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then we can run &lt;code&gt;Radio.channel(&#39;appEvents&#39;).command(&#39;log&#39;, event)&lt;/code&gt; anywhere we want to log an application event.  We could use events for this, but there&amp;rsquo;s value in using commands.  We&amp;rsquo;re explicitly saying that we want our application to log a specific piece of data, whereas a similar event would have the connotation that an event had occured, and anything that wanted to respond to it could.  We can be more confident of what&amp;rsquo;s happening here.&lt;/p&gt;
&lt;h4 id=&#34;share-resources-across-nested-views-with-requests&#34;&gt;Share Resources Across Nested Views with Requests&lt;/h4&gt;
&lt;p&gt;One of the challenges of nested View architectures like Marionette or ReactJS is deciding how to pass data down to deeply nested View components.  One approach is to pass all necessary data into the top level view and then pass it down along the View tree to whatever View needs it.  That has the advantage of a clear data flow, but the disadvantage of cluttering up parent Views with data they don&amp;rsquo;t need and tightly coupling the parent Views to the implementation of their children.  Another approach is simply making the data available globally, which has all the disadvantages that global data normally brings.  Radio requests provide a nice solution to this problem.  You can define &amp;ldquo;data providers&amp;rdquo; that are responsible for providing any data you need that is not passed directly down a view chain. These could be separate modules similar to Angular&amp;rsquo;s service objects.  They could be other UI components like a datepicker.  Or they could just be models and collections you define at the root of your application but don&amp;rsquo;t pass directly to your Views.  In the same application as above, I have a set of task views that can have users assigned to them.  Because these tasks are deeply nested in the UI, I don&amp;rsquo;t pass the collection of possible Users to assign down the View tree.  Instead, I define that collection within my top level application object and then request it when the user opens up the user-picker View.  I use jQuery deferreds to make sure that the collection has been populated before the picker appears.  That all looks something like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;//in app.js
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; usersDeferred &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; (&lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; UserCollection()).fetch();
resourceChannel.reply(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;userlist&amp;#39;&lt;/span&gt;,&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;() {
    &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; usersDeferred;
});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;//in task.js
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; usersDeferred &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; resourceChannel.request(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;userlist&amp;#39;&lt;/span&gt;);
usersDeferred.done(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.showUserPicker);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;a-quick-note-on-backboneradio-and-marionette&#34;&gt;A Quick Note on Backbone.Radio and Marionette&lt;/h3&gt;
&lt;p&gt;Those of you who have used Marionette before may be a bit confused as to why this post is part of my Marionette article.  As of version 2.3, the current shipping version of Marionette, Radio is not distributed as part of the library.  Marionette instead ships with &lt;a href=&#34;https://github.com/marionettejs/backbone.wreqr&#34;&gt;Backbone.Wreqr&lt;/a&gt; as its message bus implementation.  Wreqr is a precursor to Radio with a significantly more confusing API.  Radio provides a cleaner approach, as well as a more intuitive name.  However, because Marionette follows semantic versioning, they&amp;rsquo;re waiting for 3.0 to make Radio the default.&lt;/p&gt;
&lt;p&gt;In the meantime, though, it&amp;rsquo;s easy to replace Wreqr with Radio.  You can simply make sure that you&amp;rsquo;re loading in Radio instead of Wreqr, and then implement the following &lt;a href=&#34;https://gist.github.com/thejameskyle/48afb443b8c8c6ee4f46&#34;&gt;shim&lt;/a&gt;:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;(function(root, factory) {
  if (typeof define === &#39;function&#39; &amp;amp;&amp;amp; define.amd) {
    define([&#39;backbone.marionette&#39;, &#39;backbone.radio&#39;, &#39;underscore&#39;], factory);
  } else if (typeof exports !== &#39;undefined&#39;) {
    module.exports = factory(require(&#39;backbone.marionette&#39;), require(&#39;backbone.radio&#39;), require(&#39;underscore&#39;));
  } else {
    factory(root.Backbone.Marionette, root.Backbone.Radio, root._);
  }
}(this, function(Marionette, Radio, _) {
  &#39;use strict&#39;;

  Marionette.Application.prototype._initChannel = function () {
    this.channelName = _.result(this, &#39;channelName&#39;) || &#39;global&#39;;
    this.channel = _.result(this, &#39;channel&#39;) || Radio.channel(this.channelName);
  }
}));
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It&amp;rsquo;s also worth pointing out that Radio has no direct dependency on Marionette, and can be used on any Backbone project.  For example, it might be an interesting tool to implement a Flux-style dispatcher in an application using Backbone and React. All of the benefits Radio provides can help any application with decoupled View components.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Thanks to the Marionette Teams for the diagrams above, which come directly from the Backbone.Radio &lt;a href=&#34;https://github.com/marionettejs/backbone.radio&#34;&gt;README&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&#34;more-resources&#34;&gt;More Resources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Although it&amp;rsquo;s focused on Node and backend use cases, &lt;a href=&#34;https://www.youtube.com/watch?v=rWz8OoVuDls&#34;&gt;this video&lt;/a&gt; is a great rundown of semantic messaging patterns.&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Is Bower Useful?</title>
      <link>https://benmccormick.org/2015/01/21/235206.html</link>
      <pubDate>Thu, 22 Jan 2015 00:52:06 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2015/01/22/235206.html</guid>
      <description>&lt;p&gt;&lt;img src=&#34;bower-1.png&#34; alt=&#34;bower logo&#34;&gt;&lt;/p&gt;
&lt;p&gt;I first heard about &lt;a href=&#34;http://bower.io/&#34;&gt;Bower&lt;/a&gt; about a year and half ago, and was immediately confused.  Bower is branded as a package manager for the web.  My immediate question: &amp;ldquo;Why create another package manager for JavaScript, when &lt;a href=&#34;https://www.npmjs.com/&#34;&gt;npm&lt;/a&gt; was just starting to become a standard?&amp;rdquo;  I certainly wasn&amp;rsquo;t the only one thinking it.&lt;/p&gt;
&lt;blockquote class=&#34;twitter-tweet&#34; lang=&#34;en&#34;&gt;&lt;p&gt;&amp;quot;What&amp;#39;s bower?&amp;quot;&amp;#10;&amp;quot;A package manager, install it with npm.&amp;quot;&amp;#10;&amp;quot;What&amp;#39;s npm?&amp;quot;&amp;#10;&amp;quot;A package manager, you can install it with brew&amp;quot;&amp;#10;&amp;quot;What&amp;#39;s brew?&amp;quot;&amp;#10;...&lt;/p&gt;&amp;mdash; Stefan Baumgartner (@ddprrt) &lt;a href=&#34;https://twitter.com/ddprrt/status/529909875347030016&#34;&gt;November 5, 2014&lt;/a&gt;&lt;/blockquote&gt;
&lt;p&gt;If you can use npm to install Bower, you can use it to install packages directly.  And if you don&amp;rsquo;t like npm, is it that hard to just pull in your dependencies manually?  Why use a package manager at all?&lt;/p&gt;
&lt;p&gt;A year later, I now believe Bower is a useful and important part of the web development ecosystem, so in the interest of sharing knowledge and because I can&amp;rsquo;t resist the chance to flout &lt;a href=&#34;http://en.wikipedia.org/wiki/Betteridge%27s_law_of_headlines&#34;&gt;Betteridge&amp;rsquo;s law of headlines&lt;/a&gt;, here&amp;rsquo;s my case for why Bower is useful.&lt;/p&gt;
&lt;h3 id=&#34;manual-package-management-doesnt-scale&#34;&gt;Manual package management doesn&amp;rsquo;t scale&lt;/h3&gt;
&lt;p&gt;For quite a while I was content to manage my web dependencies manually.  I would go to a project site, hit the big download button, move the files into my project and get on with my day.  It was simple and required no setup or tools.  I was happy.  However I&amp;rsquo;m now managing a project that includes almost 30 external front end dependencies of some kind.  At that scale it&amp;rsquo;s impossible to shrug off the pain points of the &amp;ldquo;Do It Yourself&amp;rdquo; approach.&lt;/p&gt;
&lt;p&gt;The biggest problems come around keeping dependencies up to date. Simple solutions unravel quickly here.  First, while it would be lovely if every front end library included a version number in their distributed file, that&amp;rsquo;s not always the case.  So keeping track of versions reliably invariably means some sort of external documentation.  Even when I knew the version, I would have to manually go to each libraries site to see if there was a newer version, then test it, and then either keep 2 copies of the library around or mess with git branches while I was testing to see if the new version caused any problems or regressions.  That was fine with a few libraries, but it doesn&amp;rsquo;t scale well.&lt;/p&gt;
&lt;p&gt;So my advice?  Don&amp;rsquo;t try to manage your assets manually after your projects grow to a certain size.  You&amp;rsquo;ll spend unnecessary time keeping them up to date, clutter your version control logs, and will have to actually document the versions somewhere anyway.  So manual package management is out.  But why not just use npm?&lt;/p&gt;
&lt;h3 id=&#34;npm-is-the-right-answer-to-the-wrong-question&#34;&gt;npm is the right answer to the wrong question&lt;/h3&gt;
&lt;p&gt;npm is a fantastic package manager for node development.  Being able to immediately pull in a library and all of its dependencies then be confident that it will work with the module format you use is a fantastic thing, and npm has pulled it off well.  So why not just use it for all of your web development package management needs?&lt;/p&gt;
&lt;p&gt;The problem is that it&amp;rsquo;s impossible for tools to optimize for everything. npm has optimized for node development.  That leads to problems when using it in other settings.  First of all, many npm packages assume you&amp;rsquo;re using the commonJS module format.  Node encourages small modules that may have many dependencies, linked with commonJS.  It&amp;rsquo;s possible to use those modules on the front end of course if you use a tool like &lt;a href=&#34;http://browserify.org/&#34;&gt;Browserify&lt;/a&gt;, but your choice of package manager should not lock you into a specific module format or build tool.  Most major packages do distribute their code in a UMD format that can be loaded in multiple ways, but some do not, and when those packages have dependencies, we have another problem.&lt;/p&gt;
&lt;p&gt;npm has a nested dependency tree, where each module also loads all of its dependencies individually.  This is fine on the server, where you can put node_modules into your .gitignore file and effectively pretend those files are not there.  When writing client-side code though, it&amp;rsquo;s important to be efficient with bandwidth.  You can&amp;rsquo;t load multiple versions of a dependency if, for instance, you used multiple libraries that depend on Underscore or jQuery.  That&amp;rsquo;s a problem if you&amp;rsquo;re using browserify, since you&amp;rsquo;ll need to find a way to normalize those dependencies to a single file.  But nested dependencies are also annoying when using other problems, both due to the need to manually figure out what you need and avoid duplication as well as the awkwardness of making deep path references down several layers of node_modules folders.&lt;/p&gt;
&lt;p&gt;Lastly, I&amp;rsquo;d encourage people considering npm for front-end package management to use a tool scoped for their needs. npm started as a package manager for node, and that is still its main use.  There are plenty of packages that can be useful both on node and in the browser, but many things only make sense in one environment.  For instance CSS libraries are not useful within node, and file system libraries won&amp;rsquo;t work in the browser.  I&amp;rsquo;ll admit that this ship may have already sailed though. Many popular browser only libraries like Bootstrap and Angular are available on npm right now as a response to people who are using npm for everything&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;h3 id=&#34;so-why-bower&#34;&gt;So Why Bower?&lt;/h3&gt;
&lt;p&gt;The problems above explain the case for &amp;ldquo;yet another package manager&amp;rdquo;.  So now we can talk about how Bower is better.  Bower is focused on front-end development, provides a flat dependency structure, and doesn&amp;rsquo;t lock you in to a single way of doing things.  Let me break that down.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Bower is focused on the front end.&lt;/strong&gt;  If you find a package registered on bower.io, you can be confident that it will useful on the front end, and won&amp;rsquo;t be using node-specific dependencies.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Bower has a flat dependency structure.&lt;/strong&gt;  If multiple libraries require a dependency, Bower will figure out the best version to load and place it in the top level of your bower_components directory.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Bower doesn&amp;rsquo;t lock you in.&lt;/strong&gt; Nothing about Bower is specific to a certain module format or build tool.  You can use it with RequireJS and Grunt, Webpack and Gulp, or by loading scripts directly into your HTML.&lt;/p&gt;
&lt;p&gt;Bower addresses the pain points that come from manually managing your scripts or using npm.  You get easy version tracking and updating, keep your git logs clean, and can be confident that it will work cleanly with your existing setup.  If you&amp;rsquo;re starting a new project or updating your dependencies on an existing one, consider using Bower to make your life easier.&lt;/p&gt;
&lt;h3 id=&#34;more-resources&#34;&gt;More Resources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Want to hear the case for using npm in your front end development? You can find it &lt;a href=&#34;http://blog.npmjs.org/post/101775448305/npm-and-front-end-packaging&#34;&gt;on their blog&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If you&amp;rsquo;re interested in Bower, it&amp;rsquo;s also worth checking out &lt;a href=&#34;http://yeoman.io/&#34;&gt;Yeoman&lt;/a&gt;, a project for quickly scaffolding out web projects using Bower and Grunt.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;footnotes&#34;&gt;
&lt;ol&gt;
    &lt;li class=&#34;footnote&#34; id=&#34;fn:1&#34;&gt;
        &lt;p&gt;
        Something npm is clearly &lt;a href=&#34;http://blog.npmjs.org/post/101775448305/npm-and-front-end-packaging&#34;&gt;encouraging&lt;/a&gt;
        &lt;/p&gt;
        &lt;a href=&#34;#fnref:1&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>The Life of a Marionette View</title>
      <link>https://benmccormick.org/2015/01/04/230145.html</link>
      <pubDate>Mon, 05 Jan 2015 00:01:45 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2015/01/05/230145.html</guid>
      <description>&lt;p&gt;&lt;em&gt;This is the fourth post in a series on &lt;a href=&#34;http://marionettejs.com/&#34;&gt;Marionette.js&lt;/a&gt;, a framework for developing apps with &lt;a href=&#34;http://backbonejs.org/&#34;&gt;Backbone.js&lt;/a&gt;.  For more background on what Marionette is, check out the series page: &lt;a href=&#34;http://benmccormick.org/marionette-explained/&#34;&gt;Marionette Explained&lt;/a&gt;  Also note that this article was written about Marionette v2.  The current latest version of Marionette is v3, and while most of the high level concepts remain the same, the specific syntax has changed in some cases.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;When building Single Page Applications, it&amp;rsquo;s important to manage UI components throughout their existence on the page, making sure they&amp;rsquo;re properly created, attached, and destroyed.  Marionette.js helps Backbone developers manage that by providing life cycle methods that developers can use when defining their Views.  These life cycle functions fit nicely with the rest of Marionette&amp;rsquo;s features, and can help simplify UI development with Backbone.&lt;/p&gt;
&lt;p&gt;Building scalable user interfaces is hard.  It&amp;rsquo;s a challenge that sits at the intersection of fields requiring very different skill sets: Software Development, Graphic Design, User Experience and Information Architecture.  Because interface code is concerned with both presentation and interaction logic and is exposed directly to user input, it can be difficult to reason about.  Fortunately, as modern web developers, we have 30+ years of industry knowledge to fall back on.  One lesson learned is the value of Object Oriented Programming concepts in UI design; specifically, the idea of breaking interfaces into a set of independent components, and giving each component a consistent &amp;ldquo;life cycle&amp;rdquo;, a set of events that occur between a component&amp;rsquo;s creation and destruction.&lt;/p&gt;
&lt;p&gt;Having a clear life cycle for UI components makes a developer&amp;rsquo;s life easier in a few ways:  It eases the process of reasoning about changes in a component over time, and how it interacts with other elements of the UI.  It creates consistent hooks to add behaviors, which promotes readability and reduces boilerplate code.  Finally, it smooths integrations with outside code that may need to be run when the component is in a specific state, without needing a bunch of conditional logic to detect when it should run.  Marionette Views provide a life cycle for Backbone Views that help give all of these benefits.&lt;/p&gt;
&lt;p&gt;The Marionette View life cycle is made up of a list of events and conventions.  Events are fired at each signficant step in a View&amp;rsquo;s life cycle.  Each event has a corresponding View method associated with it that Marionette automatically runs when the event is fired. These events and callbacks follow a consistent naming convention.  An event that occurs before a moment in the life cycle is fired in the form &lt;code&gt;before:&amp;lt;eventname&amp;gt;&lt;/code&gt; and the callback is called &lt;code&gt;onBeforeEventName&lt;/code&gt;. An event that is fired after the same moment in the life cycle will have the form &lt;code&gt;eventname&lt;/code&gt; and the callback will be called &lt;code&gt;onEventName&lt;/code&gt;.  By default the callback functions for each event do nothing, but developers can overwrite them to define behavior for a specific View instance.  For instance, defining the callback functions for the &lt;code&gt;render&lt;/code&gt; and &lt;code&gt;before:render&lt;/code&gt; events on a new View would look like this.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; ExampleView &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; Mn.ItemView.extend({

    onRender&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;() {
        &lt;span style=&#34;color:#6272a4&#34;&gt;// do stuff after the View is rendered
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    },

    onBeforeRender&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;() {
        &lt;span style=&#34;color:#6272a4&#34;&gt;// do stuff before the View is rendered
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    }

});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Render is only one of the relevant moments in a View&amp;rsquo;s life cycle.  This is the full list of relevant methods and events, with a brief explanation of how each one might be used.&lt;/p&gt;
&lt;h4 id=&#34;initialize&#34;&gt;Initialize&lt;/h4&gt;
&lt;p&gt;The first function in a View&amp;rsquo;s life cycle is &lt;code&gt;initialize&lt;/code&gt;. &lt;code&gt;initialize&lt;/code&gt; isn&amp;rsquo;t a Marionette-specific method. It&amp;rsquo;s part of Backbone, but it&amp;rsquo;s important to make sure you understand where it fits into the View&amp;rsquo;s life.  Backbone provides two functions that are run when a View is instantiated, &lt;code&gt;constructor&lt;/code&gt; and &lt;code&gt;initialize&lt;/code&gt;.  &lt;code&gt;constructor&lt;/code&gt; is used for Backbone and Marionette&amp;rsquo;s internal setup, and shouldn&amp;rsquo;t normally be overridden.  &lt;code&gt;initialize&lt;/code&gt; is the suggested function for defining behavior on View setup.  It&amp;rsquo;s a great place for setting up event listeners, and allows workings directly with the options passed to the View on creation &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;. Unlike the other methods on this list, &lt;code&gt;initialize&lt;/code&gt; only provides a single method with no associated event.&lt;/p&gt;
&lt;h4 id=&#34;onrenderonbeforerender&#34;&gt;onRender/onBeforeRender&lt;/h4&gt;
&lt;p&gt;The second step in the Marionette View life cycle is the render step, which exposes two events &lt;code&gt;render&lt;/code&gt; and &lt;code&gt;before:render&lt;/code&gt;, corresponding to the &lt;code&gt;render&lt;/code&gt; and &lt;code&gt;onBeforeRender&lt;/code&gt; callbacks.  These events fire before and after the View template is rendered.  In a Marionette View, rendering means that the View has generated a fragment of HTML, but it may or may not be visible or attached to the DOM.  onRender is useful for any direct manipulation of the generated HTML that doesn&amp;rsquo;t require it to be visible or attached to the DOM.&lt;/p&gt;
&lt;h4 id=&#34;onattachonbeforeattach-marionette-23&#34;&gt;onAttach/onBeforeAttach (Marionette 2.3+)&lt;/h4&gt;
&lt;p&gt;After rendering, the next set of events that might fire in a Marionette View&amp;rsquo;s life cycle is &lt;code&gt;before:attach&lt;/code&gt; and &lt;code&gt;attach&lt;/code&gt;.  These events are fired whenever showing a View in a region causes it to be attached to the DOM.  Because Views can be rendered independently of Regions, and some Regions may not be attached to the DOM when a View is shown, this event may not always be fired immediately (or at all).  But if you&amp;rsquo;re using Regions to render all your Views, it can be very useful for setting up jQuery plugins or other operations that require HTML to be attached to the DOM before being acted on.  A nice aspect of the attach events is that they will propagate down a tree of LayoutViews if you&amp;rsquo;ve set up a View hierarchy as described in &lt;a href=&#34;http://benmccormick.org/2014/12/22/building-complex-layouts-with-marionette-js/&#34;&gt;my last post&lt;/a&gt;, so you can count on the event firing even if you build the View tree and then attach the top View to the DOM later.&lt;/p&gt;
&lt;h4 id=&#34;onshowonbeforeshow&#34;&gt;onShow/onBeforeShow&lt;/h4&gt;
&lt;p&gt;Another Region-specific set of events, &lt;code&gt;show&lt;/code&gt; and &lt;code&gt;before:show&lt;/code&gt; fire before and after a View is shown within a region.  These events are great for rendering child Views.  The Marionette docs recommend using &lt;code&gt;onBeforeShow&lt;/code&gt; specifically for rendering children, since it allows for only a single DOM paint when rendering nested Views, and prevents attach events from firing multiple times, which might happen if the child Views are attached to the parent after the parent View has already been shown.&lt;/p&gt;
&lt;h4 id=&#34;ondomrefresh&#34;&gt;onDomRefresh&lt;/h4&gt;
&lt;p&gt;The &lt;code&gt;dom:refresh&lt;/code&gt; event is the last Region-specific event  It&amp;rsquo;s triggered after an already shown View is rerendered.  Like onAttach, this can be useful for managing UI plugins that manipulate the DOM, if they need to be reinitialized when the HTML tree is refreshed. It differs from &lt;code&gt;onRender&lt;/code&gt; in that it will not run the first time the View is rendered, and you can count on the View always being attached to the document when it fires.  So if an operation requires the View to be attached to the DOM, you can run any initial logic in &lt;code&gt;onShow&lt;/code&gt;, and then put any refresher logic into an &lt;code&gt;onDomRefresh&lt;/code&gt; callback.  If you&amp;rsquo;re running Marionette 2.3 or later though, onDomRefresh is less useful because onAttach provides similar functionality in a more consistent way.&lt;/p&gt;
&lt;h4 id=&#34;onbeforeaddchildonbeforeremovechildonaddchildonremovechild-collectionview-only&#34;&gt;onBeforeAddChild/onBeforeRemoveChild/onAddChild/onRemoveChild (CollectionView Only)&lt;/h4&gt;
&lt;p&gt;CollectionViews get their own special life-cycle events to manage adding and removing Models to the Collection.  CollectionViews automatically display a new ChildView when a Model is added to its Collection, and destroy the View when the Model is removed.  They fire events before and after each of these changes, to allow you to customize the behavior around each.  You could for instance hide specific Views if necessary. You could also modify them based on some logic, though that type of thing may be more appropriate within the child View&amp;rsquo;s code itself.&lt;/p&gt;
&lt;h4 id=&#34;ondestroyonbeforedestroy&#34;&gt;onDestroy/onBeforeDestroy&lt;/h4&gt;
&lt;p&gt;The final Marionette life-cycle event set is &lt;code&gt;destroy&lt;/code&gt; and &lt;code&gt;before:destroy&lt;/code&gt;.  Appropriately, these events are fired when a View is destroyed and serve as a place to handle any custom cleanup.  The most common use case for these functions is unbinding any events not covered by Marionette&amp;rsquo;s built-in event cleanup&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;. It&amp;rsquo;s worth noting that you cannot use &lt;code&gt;onBeforeDestroy&lt;/code&gt; to prevent the View being destroyed.  The Marionette team&amp;rsquo;s position here is basically that you should not call destroy directly on any View you don&amp;rsquo;t want destroyed.  If you&amp;rsquo;re swapping a View out of a region but don&amp;rsquo;t want it to be destroyed, Marionette provides a &lt;code&gt;preventDestroy&lt;/code&gt; option to its show method that allows you to preserve the existing View.&lt;/p&gt;
&lt;h3 id=&#34;cogs-in-a-machine&#34;&gt;Cogs In A Machine&lt;/h3&gt;
&lt;p&gt;The nice thing about Marionette&amp;rsquo;s View life cycles is the consistency it shares with the rest of Marionette.  The life cycles are built to work with the Region and Layout system I described in my last post.  If you lay out your Views using the system described in that post, you&amp;rsquo;ll be able to take advantage of all of the above functions consistently across your application.  Regions themselves have similar life cycle methods, with callbacks that run before and after showing Views, swapping Views and emptying the region. Finally, Marionette Applications, the object that Marionette uses to initialize the app, also has a single set of life-cycle events, &lt;code&gt;onStart&lt;/code&gt; and &lt;code&gt;onBeforeStart&lt;/code&gt; that can be hooked into when setting up your application.  This sense of cohesiveness in a set of components that share conventions makes Marionette easy to learn without obscuring what happens with the type of magic you see in other frameworks.&lt;/p&gt;
&lt;h3 id=&#34;take-what-you-need&#34;&gt;Take What You Need&lt;/h3&gt;
&lt;p&gt;Like everything else in Marionette and Backbone, life cycles are a pattern that you can choose to use or ignore.  If you want to define your own way of managing a Views life cycle, it&amp;rsquo;s perfectly possible to do so.  But the advantages provided by Marionette&amp;rsquo;s implementation are quite nice.  It presents a simple mental model of what occurs to a View over time, fits in with the other patterns provided by Marionette, and doesn&amp;rsquo;t require any extra boilerplate when you choose not to use them.  I personally use some of these methods a lot, and have never used a few of them at all.  But it&amp;rsquo;s helpful to know what is available so that you can keep that simple model of how a View changes over time and choose the appropriate hook for any given View code.  Code is scalable when you can take a few simple concepts and use them repeatedly to build up to something big.  That&amp;rsquo;s what Marionette can do for you.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34;&gt;
&lt;ol&gt;
    &lt;li class=&#34;footnote&#34; id=&#34;fn:1&#34;&gt;
        &lt;p&gt;
        Marionette also exposes those options later using the &lt;code&gt;view.getOption()&lt;/code&gt; method
        &lt;/p&gt;
        &lt;a href=&#34;#fnref:1&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li class=&#34;footnote&#34; id=&#34;fn:2&#34;&gt;
        &lt;p&gt;
        Marionette cleans up events created through its event hash objects, and any defined using listenTo.  But any custom eventing stuff you do will need to be cleaned up directly
        &lt;/p&gt;
        &lt;a href=&#34;#fnref:2&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Building Complex Layouts With Marionette.js</title>
      <link>https://benmccormick.org/2014/12/21/234347.html</link>
      <pubDate>Mon, 22 Dec 2014 00:43:47 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2014/12/22/234347.html</guid>
      <description>&lt;p&gt;&lt;em&gt;This is the third post in a series on &lt;a href=&#34;http://marionettejs.com/&#34;&gt;Marionette.js&lt;/a&gt;.  For more background on what Marionette is, check out the first post in the series, &lt;a href=&#34;http://benmccormick.org/2014/12/02/the-case-for-marionette-js/&#34;&gt;The Case For Marionette&lt;/a&gt;  Also note that this article was written about Marionette v2.  The current latest version of Marionette is v3, and while most of the high level concepts remain the same, the specific syntax has changed in some cases.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;When building complex web applications, many of the first decisions you have to make revolve around the structure and layout of your application. Most applications will have some static portions like navigations or footers, and some dynamic portions holding content or page specific controls.  A good layout manager will allow you to easily control these layouts, helping you keep structure consistent between pages and actions while swapping out content on changes in routes or data.&lt;/p&gt;
&lt;p&gt;Backbone provides Views as a way of managing the display of a web app&amp;rsquo;s UI.  But it doesn&amp;rsquo;t provide any guidance on how you should use them to construct complex layouts.  Should you have one view per page and control the layout with templates and jQuery?  Use one View for each section of the page?  Or have a top level view that creates child views to manage different sections?  All of these are possible with Backbone, and none of them are particularly encouraged or discouraged by the library design.  In fact because Backbone doesn&amp;rsquo;t provide any consistent conventions for managing subviews, rendering content, or attaching rendered content to the DOM, even projects that take the same approach to managing layout might implement these patterns quite differently.&lt;/p&gt;
&lt;p&gt;In my &lt;a href=&#34;http://benmccormick.org/2014/12/02/the-case-for-marionette-js/&#34;&gt;first post&lt;/a&gt;, I talked about how one of the strengths of Marionette is the way it helps remove many of the decisions that Backbone developers have to make for each project by providing components based on community-tested patterns.  Layout is another area where Marionette can give you a standardized solution.  Marionette does this by providing Regions and by making it easy to manage child Views.&lt;/p&gt;
&lt;h3 id=&#34;layout-in-marionette&#34;&gt;Layout in Marionette&lt;/h3&gt;
&lt;p&gt;Regions are the primary tool Marionette provides for defining layouts.  A Region is a defined portion of the page, held within a root DOM element. You can swap different Views in and out of Regions, or show one View and let it stay there permanently.  Like everything in Backbone applications, Regions emit events, which allow you to design functionality that is triggered before or after a region&amp;rsquo;s content changes.  Regions map very well to low fidelity layout wireframes like the one below, but they also can be used for organizing smaller components.  They&amp;rsquo;re an organization tool for attaching and removing Views in a consistent way.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;marionette_regions-1.png&#34; alt=&#34;Regions image&#34;&gt;&lt;/p&gt;
&lt;p&gt;Regions really shine when it comes to child Views.  When you&amp;rsquo;re setting up Views in a normal Backbone application, you have to be very careful to avoid memory leaks by replacing a view without properly destroying it, especially for long-running SPA style apps. If you&amp;rsquo;re properly cleaning up Views when they&amp;rsquo;re destroyed, another thing that Marionette can help with, Regions remove that pain by ensuring that a View is properly destroyed if replaced in a Region, removing boilerplate and the opportunity for subtle memory bugs.  They also provide a clean central way to attach child Views, making it easier to maintain consistency across a project and promoting readability when moving into different code.&lt;/p&gt;
&lt;h3 id=&#34;layoutview&#34;&gt;LayoutView&lt;/h3&gt;
&lt;p&gt;Regions are great, but for the most part you&amp;rsquo;re not going to want to use them directly.  Instead, Marionette provides a special View class, LayoutView.  LayoutViews allow you to build View tree hierarchies.  You can have one top level View that controls the entire page, or a section of the page that your Marionette app lives in.  That root view can then contain Regions which you use to show child Views.  Some of those child Views may themselves be LayoutViews, and so on for as many levels as you like.  This setup allows you to create modular View classes with few responsibilities that you can easily replace or update without having to write a lot of boilerplate code.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s the high level overview, but let&amp;rsquo;s dig into what the code looks like.  To use regions in a LayoutView, we don&amp;rsquo;t have to directly create them.  Instead we define a regions object that works similarly to the events object on normal Backbone Views.  The regions object takes a Region name as a key and a jQuery selector as a value, and then create Region objects for each key-value pair and attach them to the View.  If you need to do something more complicated you can create a regions function that returns an object with the key-value pairs that you would like.  Here&amp;rsquo;s an example of what a LayoutView might look like in practice.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; Mn &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; require(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;backbone.marionette&amp;#39;&lt;/span&gt;);
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; Radio &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; require(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;backbone.radio&amp;#39;&lt;/span&gt;);
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; FooterView &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; require(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;views/footer&amp;#39;&lt;/span&gt;);
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; HeaderView &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; require(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;views/header&amp;#39;&lt;/span&gt;);
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; IndexView &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; require(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;views/index&amp;#39;&lt;/span&gt;);

&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; RootView &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; Mn.LayoutView.extend({

  regions&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; {
    header&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;#navbar&amp;#39;&lt;/span&gt;,
    content&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;.content-area&amp;#39;&lt;/span&gt;,
    footer&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;footer&amp;#39;&lt;/span&gt;
  },

  initialize&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;() {
    Radio.channel(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;root&amp;#39;&lt;/span&gt;).comply(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;set:content&amp;#39;&lt;/span&gt;,&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(contentView) {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.getRegion(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;content&amp;#39;&lt;/span&gt;).show(contentView);
    });
  },

  onBeforeShow&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;() {
    &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.getRegion(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;header&amp;#39;&lt;/span&gt;).show(&lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; HeaderView());
    &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.getRegion(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;footer&amp;#39;&lt;/span&gt;).show(&lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; FooterView());
    &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.getRegion(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;content&amp;#39;&lt;/span&gt;).show(&lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; IndexView());
  }

});

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is an example of a RootView that could be shown in a standalone Region and used as the top-level of a View hierarchy.  There are a few things to note about this example.  It defines 3 regions, a header and footer that render static Views, and a content area that originally contains an index View.  The initialize function uses Backbone.Radio to listen for commands and can swap out the View held in the content region when commanded. Those views could be swapped based on users navigating to a new route, with the routes initializing the Views and passing the commands, or based on a data change of some type.  We can also see that the child Views are shown within the onBeforeShow callback.  I&amp;rsquo;ll be discussing View life-cycle methods more in my next post, but for now just know that onBeforeShow runs immediately before a View is shown in a region.  You can use it when nesting your Views in order to make sure your Views are only attached to the DOM once, which prevents the browser from having to repaint the window multiple times.&lt;/p&gt;
&lt;h3 id=&#34;its-turtles-all-the-way-down&#34;&gt;It&amp;rsquo;s Turtles All The Way Down&lt;/h3&gt;
&lt;p&gt;The great thing about Marionette&amp;rsquo;s View system is that you can take the 3 Views I&amp;rsquo;ve gone over in my last 2 posts, ItemView, CollectionView, and LayoutView, and use them to represent pretty much any layout you&amp;rsquo;d like.  The basic rules: LayoutViews are used to structure the page into regions and regions into subregions. ItemViews are used to bind data to a UI, and CollectionViews are used to iterate over a Collection when each item in a Collection has complex data or behaviors associated with it and should be bound to an individual View or View tree&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;. This consistency makes it easy to learn how to structure Marionette apps, and makes it simple for experienced Marionette developers to jump into a new project quickly and get their bearings.  That&amp;rsquo;s really the promise of Marionette in a nutshell: consistent patterns that allow for a better development experience.&lt;/p&gt;
&lt;h3 id=&#34;more-resources&#34;&gt;More Resources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;For more on nesting Marionette Views, you can check out &lt;a href=&#34;https://www.youtube.com/watch?v=CTr-tTwRH3o&#34;&gt;this talk&lt;/a&gt; by Marionette core team member Sam Saccone.  It&amp;rsquo;s a quick 10 minute video covering much of the same stuff I went through here.&lt;/li&gt;
&lt;li&gt;I&amp;rsquo;ll talk more about this in a future post, but if you have a Marionette app and want to visualize your View hierarchy, &lt;a href=&#34;https://github.com/marionettejs/marionette.inspector&#34;&gt;Marionette Inspector&lt;/a&gt; is a great new tool for debugging Marionette apps, and it&amp;rsquo;s primary developer, Jason Lastner gave a &lt;a href=&#34;https://www.youtube.com/watch?v=jbGm3mJXh_s&#34;&gt;great talk&lt;/a&gt; describing how to use it at BackboneConf this week.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;footnotes&#34;&gt;
&lt;ol&gt;
    &lt;li class=&#34;footnote&#34; id=&#34;fn:1&#34;&gt;
        &lt;p&gt;
        Marionette also contains a 4th View type, CompositeView.  But it&#39;s essentially a helper for the case where you want to display a CollectionView inside a region of a LayoutView, and isn&#39;t strictly necessary.  Technically you can also use LayoutViews to replace ItemViews, but the semantic difference is useful for encouraging readability.
        &lt;/p&gt;
        &lt;a href=&#34;#fnref:1&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Come Build With Me</title>
      <link>https://benmccormick.org/2014/12/18/090000.html</link>
      <pubDate>Thu, 18 Dec 2014 10:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2014/12/18/090000.html</guid>
      <description>&lt;p&gt;One of the blessings of starting this blog has been the opportunity to answer questions, debate, and learn from the amazingly knowledgeable people who have read my posts.  I&amp;rsquo;ve talked with so many developers who have incredible enthusiasm for software development and the web platform.  If that&amp;rsquo;s you, I have a cool opportunity I want to share.&lt;/p&gt;
&lt;p&gt;I try to stay on-topic on this blog and don&amp;rsquo;t talk about myself very much, but last winter I joined &lt;a href=&#34;http://www.windsorcircle.com&#34;&gt;Windsor Circle&lt;/a&gt;, a tech startup in Durham North Carolina. We&amp;rsquo;re a software as a service company focused on helping marketers retain their customers.  Since joining, it&amp;rsquo;s been a crazy ride.  Last April, we were selected as the winner of &lt;a href=&#34;https://www.googleforentrepreneurs.com/startup-communities/the-tech-hub-network-demo-day/&#34;&gt;Google&amp;rsquo;s &amp;ldquo;Tech Hub Demo Day&amp;rdquo;&lt;/a&gt;, a competition where Google brought in 10 leading startups from around the country and gave them the opportunity to pitch to an auditorium full of Silicon Valley venture capitalists.&lt;/p&gt;
&lt;p&gt;This summer we followed that up by raising 6.5 million in Series B funding, and we&amp;rsquo;re now growing rapidly.  Part of that growth is building out our front end development team, and we have a Front End Developer position that is open now.&lt;/p&gt;
&lt;p&gt;I want to work with great people, so here&amp;rsquo;s my no BS pitch to any JavaScript developers out there.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Come live (stay?) in Durham NC, get great weather, big city resources for small city cost of living, and amazing food &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Work with a small but growing development team that has a good mix of senior and less experienced developers.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Help build and shape an ambitious web app built with Backbone and Marionette.js on top of a Python backend&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Work with a &lt;a href=&#34;http://www.windsorcircle.com/team&#34;&gt;team&lt;/a&gt; that has a lot of fun while taking care of their work like professionals and places a genuine emphasis on the &lt;a href=&#34;http://www.windsorcircle.com/about-us/our-values&#34;&gt;company&amp;rsquo;s values.&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You can even get paid for all of this.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Finally, if you&amp;rsquo;re interested, we&amp;rsquo;re open to a mix of experience levels.  The main thing we want to see is JavaScript and programming knowledge that matches up to where you are right now, and an enthusiasm for building things on the web.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In all seriousness, if this sounds interesting to you, feel free to get in touch &lt;a href=&#34;mailto:ben.mccormick@windsorcircle.com&#34;&gt;by email&lt;/a&gt; or on &lt;a href=&#34;http://www.twitter.com/_benmccormick&#34;&gt;Twitter&lt;/a&gt;.  You can also see the full job description and apply directly &lt;a href=&#34;https://hire.jobvite.com/Jobvite/Job.aspx?b=nMUoipwg&amp;amp;j=oZqQZfwY&#34;&gt;on jobvite&lt;/a&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;div class=&#34;footnotes&#34;&gt;
&lt;ol&gt;
    &lt;li class=&#34;footnote&#34; id=&#34;fn:1&#34;&gt;
        &lt;p&gt;
        Durham&#39;s been getting &lt;a href=&#34;http://www.newsobserver.com/2014/08/14/4071138_durham-gets-more-love-from-bon.html?rh=1&#34;&gt;national attention&lt;/a&gt; for its food scene for several years now.
        &lt;/p&gt;
        &lt;a href=&#34;#fnref:1&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Marionette Explained: Connecting Data to Your Views</title>
      <link>https://benmccormick.org/2014/12/10/073000.html</link>
      <pubDate>Wed, 10 Dec 2014 08:30:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2014/12/10/073000.html</guid>
      <description>&lt;p&gt;&lt;em&gt;This is the second post in a series on &lt;a href=&#34;http://marionettejs.com/&#34;&gt;Marionette.js&lt;/a&gt;.  For more background on what Marionette is, check out the first post in the series, &lt;a href=&#34;http://benmccormick.org/2014/12/02/the-case-for-marionette-js/&#34;&gt;The Case For Marionette&lt;/a&gt;.  Also note that this article was written about Marionette v2.  The current latest version of Marionette is v3, and while most of the high level concepts remain the same, the specific syntax has changed in some cases.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;One of the most interesting design choices of &lt;a href=&#34;http://backbonejs.org/&#34;&gt;Backbone&lt;/a&gt; was the decision to not provide a default render function for Views. Backbone Views by default are an empty function that adds nothing to the DOM when rendered.  Although a View can have a Model or Collection associated with it, there is no built in way to associate that with the generated View.  When you contrast that to other modern frameworks like Ember, Angular and KnockoutJS, and their emphasis on using 2 way bindings to associate a data object to a rendered View, Backbone can feel a bit incomplete.  The goal is to allow for a variety of rendering approaches, without making one of them a favored approach.  But it leaves a situation where choosing a rendering procedure is one of the first steps in any new Backbone project.  Marionette provides a structured approach for binding your data to your view layer, while still providing flexibility to introduce customization.&lt;/p&gt;
&lt;h3 id=&#34;rendering-and-data-binding-in-marionette&#34;&gt;Rendering and Data-Binding in Marionette&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;renderpattern-3.png&#34; alt=&#34;rendering diagram&#34;&gt;&lt;/p&gt;
&lt;p&gt;Marionette.JS handles rendering in a way that is similar to the &lt;a href=&#34;http://en.wikipedia.org/wiki/Model_View_ViewModel&#34;&gt;Model-View-ViewModel&lt;/a&gt; pattern that developers who have used KnockoutJS or Durandal will be familiar with &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;. Marionette implements its render cycle through 2 primary methods available in all of its base View classes.  The first is &lt;code&gt;serializeData&lt;/code&gt;. serializeData is a function that produces what is essentially a &lt;code&gt;ViewModel&lt;/code&gt; in the sense of an MVVM application. It takes your data (a Backbone Model or Collection), and pulls it into a simplified form that a View can easily render.  By default Marionette will simply call the Model or Collection&amp;rsquo;s &lt;code&gt;toJSON&lt;/code&gt; function to serialize the Backbone object down into a simple JavaScript object.  But it&amp;rsquo;s possible to override serializeData to provide more complicated logic.  For instance here&amp;rsquo;s an example from the &lt;a href=&#34;https://github.com/tastejs/todomvc/tree/gh-pages/examples/backbone_marionette&#34;&gt;Marionette TodoMVC project&lt;/a&gt; that takes a collection of todos and calculates a few values to show the number of completed todos.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;serializeData&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt; () {
    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; active &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.collection.getActive().length;
    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; total &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.collection.length;

    &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; {
        activeCount&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; active,
        totalCount&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; total,
        completedCount&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; total &lt;span style=&#34;color:#ff79c6&#34;&gt;-&lt;/span&gt; active
    };
},
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Once the serialized data/view model has been prepared, data is passed to the render function which starts by looking for a template to render.  In Marionette, templates are defined by setting the template property on your View, or by setting a getTemplate method if you want to conditionally load your templates. The render function takes that template, passes it the serialized data, and renders it using a template engine.  The default Marionette template engine is Underscore, which makes sense since it&amp;rsquo;s a Backbone dependency already.  But it&amp;rsquo;s easy to switch to a different templating engine.  Here&amp;rsquo;s the entire chunk of code I wrote to use Handlebar templates in Windsor Circle&amp;rsquo;s Marionette app.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;//render templates with Handlebars instead of Underscore
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;Backbone.Marionette.Renderer.render &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(template, data){
    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; renderer &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; Handlebars.compile(template);
    &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; renderer(data);
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;itemview-and-collectionview&#34;&gt;ItemView and CollectionView&lt;/h3&gt;
&lt;p&gt;Marionette provides several View classes that you can use as bases, but the core Views for representing data are ItemView and CollectionView.  An ItemView takes a single data object, either a Model or Collection and passes it to the template to render.  A CollectionView iterates over a Collection and renders a child View for each Model. You can either use the same View for every Collection, or mix and match Views based on the Model&amp;rsquo;s properties.&lt;/p&gt;
&lt;p&gt;So for instance, views for a simple todo list might look something like this &lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; TodoView&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; Marionette.ItemView.extend({
    tagName&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;li&amp;#39;&lt;/span&gt;,
    template&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;&amp;lt;span class=&amp;#34;checkbox&amp;#34; {{checked}}&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;#34;text&amp;#34;&amp;gt;{{ text}}&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;#34;delete&amp;#34;&amp;gt;&amp;lt;/span&amp;gt;&amp;#39;&lt;/span&gt;,
    events&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; {
        &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;click .checkbox&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;toggleChecked&amp;#39;&lt;/span&gt;,
        &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;click .delete&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;deleteItem&amp;#39;&lt;/span&gt;
    },

    serializeData&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;() {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; {
            checked&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.model.get(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;checked&amp;#39;&lt;/span&gt;) &lt;span style=&#34;color:#ff79c6&#34;&gt;?&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;checked&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;,
            text&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.model.get(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;text&amp;#39;&lt;/span&gt;)
        };
    },

    toggleChecked&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;() {
        &lt;span style=&#34;color:#6272a4&#34;&gt;//logic for checking the box
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    },

    deleteItem &lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt; () {
        &lt;span style=&#34;color:#6272a4&#34;&gt;//logic for deleting the todo
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    }
});

&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; TodoListView &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; Marionette.CollectionView.extend({
    childView&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; TodoView,
    tagName&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;ul&amp;#39;&lt;/span&gt;

});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;When the TodoListView is given a collection and rendered, it will display an unordered list of rendered TodoViews, with the data for each model bound to the template object associated with TodoView.&lt;/p&gt;
&lt;h3 id=&#34;a-brief-note-on-2-way-data-binding&#34;&gt;A brief note on 2 way data-binding&lt;/h3&gt;
&lt;p&gt;Marionette data-binding is one-way by default.  Over the last few years the discussion around data-binding has gone from &amp;ldquo;cool there&amp;rsquo;s structured data-binding&amp;rdquo; when Backbone first came out, to &amp;ldquo;how can you ship without 2-way data-bindings?&amp;rdquo; when Knockout, Angular and Ember popularized the 2-way approach, to &amp;ldquo;1 way bindings keep things simple and they&amp;rsquo;re cool again&amp;rdquo; based on the popularity of React.  I&amp;rsquo;m not going to go deep into that debate during this post, but the important takeaway is that Marionette generally prefers explicit bindings to implicit.  So when model values change, it will be based on code that you&amp;rsquo;ve written, not implicit library code.&lt;/p&gt;
&lt;h3 id=&#34;wrap-up&#34;&gt;Wrap-Up&lt;/h3&gt;
&lt;p&gt;I kept things pretty simple in this post, but consistent data binding is a core part of what Marionette provides.  Having a single documented system for attaching Model and Collection data to Views is a big win for keeping Backbone applications lean and readable.  When using these conventions you can move from View to View or project to project and quickly pick up on the intent and structure of the code.  Instead of trying to solve these problems for every  View, you can rely on the experience of others and focus on writing code to achieve your application&amp;rsquo;s goals.&lt;/p&gt;
&lt;p&gt;This was a short but important start to diving deeper into Marionette. I&amp;rsquo;ll talk more about layouts, view life-cycles, and other Marionette features in future posts, but at their heart, web applications are about exposing data in rich UIs.  Without that core, your web applications won&amp;rsquo;t have much function at all.  So make sure to understand and take advantage of this aspect of Marionette before you move on to anything else.&lt;/p&gt;
&lt;h3 id=&#34;more-resources&#34;&gt;More Resources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;If you absolutely must have 2 way data bindings in Backbone, &lt;a href=&#34;http://nytimes.github.io/backbone.stickit/&#34;&gt;Backbone.stickit&lt;/a&gt; is a good project to check out.  At Windsor Circle we use it for binding model data to forms (2 way data-binding&amp;rsquo;s best use case).  Rather than the template based approach most libaries use for 2 way data-binding, stickit allows you to configure bindings declaratively in your view code.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;footnotes&#34;&gt;
&lt;ol&gt;
    &lt;li class=&#34;footnote&#34; id=&#34;fn:1&#34;&gt;
        &lt;p&gt;
        MVVM is normally associated with 2 ways bindings though, which Backbone and Marionette do not provide
        &lt;/p&gt;
        &lt;a href=&#34;#fnref:1&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li class=&#34;footnote&#34; id=&#34;fn:2&#34;&gt;
        &lt;p&gt;
        In practice Marionette developers would likely use a ui hash on the TodoView, pull the template out into a separate file, and might have the CollectionView be a CompositeView to provide structure around the list.  But I&#39;ll dive into all of those things in more detail in future posts.
        &lt;/p&gt;
        &lt;a href=&#34;#fnref:2&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>The Case For Marionette.js</title>
      <link>https://benmccormick.org/2014/12/01/205352.html</link>
      <pubDate>Mon, 01 Dec 2014 21:53:52 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2014/12/02/205352.html</guid>
      <description>&lt;p&gt;Building large web applications using &lt;a href=&#34;http://backbonejs.org/&#34;&gt;Backbone.js&lt;/a&gt; can be hard.  Backbone is a great tool, but it&amp;rsquo;s designed to be minimalist and useful in a wide variety of situations.  As a result, you get less guidance and support from the tool as you scale up than you do from more opinionated frameworks like &lt;a href=&#34;https://angularjs.org/&#34;&gt;Angular&lt;/a&gt; and &lt;a href=&#34;http://emberjs.com/&#34;&gt;Ember&lt;/a&gt;.  When a Backbone application grows, maintaining it requires adding structure, either through a custom set of conventions and components, or based on somebody elses framework.  There are a lot of different Backbone frameworks out there, but I want to make the case for using &lt;a href=&#34;http://marionettejs.com/&#34;&gt;Marionette.js&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;marionettelogo.png&#34; alt=&#34;Marionette Logo&#34;&gt;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve been using Marionette for the past year, and it&amp;rsquo;s been incredibly valuable.  It&amp;rsquo;s really helped ease a lot of the initial issues I found with scaling out Backbone.  But there was one big issue with Marionette when I started with it. It was not simple to figure out how exactly I should be using it.&lt;/p&gt;
&lt;p&gt;When I start to use a new piece of software, I&amp;rsquo;m always hoping to see 2 types of documentation.  The first is the nitty-gritty stuff that most people associate with documentation.  What are the APIs available, what can you pass to them, what components, features, or functions does it provide?  The second type is what I think of as the &amp;ldquo;story telling&amp;rdquo; documentation.  It overlaps a bit with marketing, but basically it&amp;rsquo;s the documentation that explains the value of the software, gives you ideas on how you might use it, and outlines the philosophy that lead to the tool.  Without the first type of documentation you end up with an exciting idea that you may struggle to implement.  Without the second type, you can end up with a lot of nice tools that you aren&amp;rsquo;t sure how to combine together.&lt;/p&gt;
&lt;p&gt;Marionette is great, but it&amp;rsquo;s a tool that doesn&amp;rsquo;t have much of the story telling documentation I mentioned above.  It gets off to a good start, with the following intro on its website:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Backbone.Marionette is a composite application library for Backbone.js that aims to simplify the construction of large scale JavaScript applications.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;It is a Collection of common design and implementation patterns found in the applications that we have been building with Backbone, and includes pieces inspired by composite application architectures, event-driven architectures, messaging architectures, and more.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;But the site fails to follow through on explaining the values or philosophy that went into building it.  Instead, when you start with Marionette you&amp;rsquo;re left with a bunch of components that are well documented individually, without much guidance on how to put them together or use them.  Any explanation of the value added is scoped to an individual component in the docs, and there&amp;rsquo;s no real indication of why these particular components are bundled together. I&amp;rsquo;m going to try and provide this type of high level explanation of the value that Marionette can bring, laying out the big picture in this piece and then digging into each area of value in future posts.  To start, let&amp;rsquo;s look at the problems that Marionette is trying to solve.&lt;/p&gt;
&lt;h3 id=&#34;decisions-decisions&#34;&gt;Decisions, Decisions&lt;/h3&gt;
&lt;p&gt;Developing with Backbone is an exercise in decision making.  Backbone provides you with a minimalist set of Models and Collections that essentially serve as light wrappers around JavaScript objects synced over Ajax. It provides you lightweight Views that associate an object with a DOM node and some data.  It provides a router that associates URLs with function, and it provides helpers for managing events between all of these options.  That leaves Backbone developers with many questions to answer.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;How do you render Views?&lt;/strong&gt; - By default, Backbone&amp;rsquo;s render method does nothing. To use it, you need to fill in your own rendering function.  That could use a templating system like Underscore templates or Handlebars, jQuery manipulation of the DOM, or simple string inserts with &lt;code&gt;.innerHTML()&lt;/code&gt;.  You could use the same method for every View, or mix it up and use different methods for different Views.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;How do you manage relationships between objects?&lt;/strong&gt; - By default Backbone provides a way to manage sets of Models as a Collection, but it doesn&amp;rsquo;t have any built-in utilities for handling nested Models or Collections.  And if you want to nest your Views you&amp;rsquo;re completely on your own.  You can have a View manage it&amp;rsquo;s child Views, have a single object that manages all Views, or let each View manage itself.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;How do your Views communicate between each other?&lt;/strong&gt; - Views will often need to communicate with each other.  If for instance one View needs to change the contents of another area of the page, it could do so directly through jQuery, could get a direct reference to a View managing that area and call a function on it, change a Model that another View listens to, adjust a URL that a router listens to, or fire an event that another View could respond to. Apps can use some combination of all of these methods.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;How do you avoid repeating yourself?&lt;/strong&gt; - If you&amp;rsquo;re not careful, Backbone can involve a lot of boilerplate.  Taking the naive approach, you could end up writing rendering code, View management code and event management code over and over again in every View.  If you try to get around that using inheritance, you can end up with brittle designs that require you to make calls down to a Views prototype when you want View specific code.  Avoiding that type of repetition and the maintenance overhead it brings is a challenge.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;How do you manage a View&amp;rsquo;s life-cycle??&lt;/strong&gt; - What code is responsible for rendering a View?  Does it render itself on creation?  Or is it the responsibility of the object creating it?  Does it get attached to the DOM immediately on render? Or is that a separate step?  When the View is removed from the DOM or deleted, how do you handle any cleanup that is needed?&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;How do you structure your application?&lt;/strong&gt; - How do you get your app started?  Do you have a central object that starts everything, or is it more distributed?  If you do centralize, do you use the router to start things, or provide some other object for managing your code?&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;How do you prevent memory leaks?&lt;/strong&gt; - If your application is a &lt;a href=&#34;http://en.wikipedia.org/wiki/Single-page_application&#34;&gt;Single Page Application&lt;/a&gt; or it contains long lasting interactive sections, another issue that you may need to deal with is memory leaks.  It can be easy to create &amp;ldquo;zombie Views&amp;rdquo; in Backbone if you&amp;rsquo;re not attentive to the need to unregister events attached to a View after you&amp;rsquo;re done with it.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That&amp;rsquo;s just a small sample of the type of decision making that you have to make for a Backbone project.  Those questions signify flexibility, but they also represent mental overhead.  If you&amp;rsquo;re like me, you see these common problems and think that you can get better results relying on a shared solution that leverages the experience of the community.&lt;/p&gt;
&lt;h3 id=&#34;what-does-marionette-give-you&#34;&gt;What does Marionette Give You?&lt;/h3&gt;
&lt;p&gt;Marionette is an attempt to provide this type of shared solution, capturing Backbone best practices as a set of components and design patterns.  So what value does it provide?  Marionette gives you:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;A Standardized Rendering process&lt;/strong&gt; - Marionette takes an opinionated stand on how Views should be rendered.  Without any additional configuration, it will take a template that you specify with a View&amp;rsquo;s template property, compile it with Underscore&amp;rsquo;s templating function and pass it a model or collection.  If you need to pass it other data, or want to use a different template library, Marionette provides hooks to customize that process in a &lt;a href=&#34;http://en.wikipedia.org/wiki/Don%27t_repeat_yourself&#34;&gt;DRY&lt;/a&gt; way.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A consistent View lifecycle&lt;/strong&gt; - Marionette defines a consistent View life cycle where Views are initialized, rendered, shown, refreshed, and destroyed.  Each of these events has events and callbacks associated it, and any common boilerplate associated with them is handled behind the scenes.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The ability to define and manage complex layouts&lt;/strong&gt; - Marionette provides region objects that define portions of the DOM that can display and swap out Views.  Combined with utilities to manage child views, you can easily create deeply nested View structures with Marionette while minimizing complexity.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A central event bus with semantic events to simplify communication between Views&lt;/strong&gt; - Marionette includes Backbone.Wreqr or Backbone Radio as an event bus to allow communication between Views without explicitly coupling them.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Helpers to help you write DRY Code&lt;/strong&gt; - In addition to centralizing the rendering and view management code, Marionette provides hooks to allow you to abstract away details of the DOM and events in your View code, and a mechanism to pull common ui operations out into separate reusable objects&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Helpers to avoid &amp;ldquo;Zombie Views&amp;rdquo; and memory leaks&lt;/strong&gt; - Marionette&amp;rsquo;s lifecycle includes an explicit destroy phase that cleans up many common sources of memory leaks, and provides a hook for you to take care of the rest&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A central Application object to initialize your application&lt;/strong&gt; - Using Marionette, you&amp;rsquo;re able to specify a set of initializers that run any code that needs to be executed before your application starts, providing a clear structure and starting point to your app.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That&amp;rsquo;s not the complete feature set, but it is the essential sales pitch.  I&amp;rsquo;ll be digging deeper into each of these advantages over my next few posts, but the important thing to understand is that Marionette provides a framework for building Backbone apps that builds on established practices from the community.  If you&amp;rsquo;re building a Backbone application and want to focus on the problems that are specific to your application, Marionette is a great way to move past common issues and focus on what&amp;rsquo;s unique to you.&lt;/p&gt;
&lt;h3 id=&#34;more-resources&#34;&gt;More Resources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;For a practical introduction to Marionette, you could do much worse than &lt;a href=&#34;https://www.youtube.com/watch?v=PrQSpdWkN6Q&#34;&gt;this talk&lt;/a&gt; from the recent Nodevember conference.  Jeremy Fairbank, a member of the Marionette core team, explained how you can use Marionette to improve the architecture of your Backbone apps.&lt;/li&gt;
&lt;li&gt;The resource that best helped me understand Marionette isn&amp;rsquo;t technically about Marionette at all.  Derek Bailey&amp;rsquo;s book &lt;a href=&#34;https://leanpub.com/building-backbone-plugins?a=3a4Srv2pP9p87WQ_eoDoGp&#34;&gt;Building Backbone Plugins&lt;/a&gt; lays out the philosophy and thinking behind Marionette without directly referencing it, explaining the challenges that he faced in building a useful abstraction over Backbone.  You can read my &lt;a href=&#34;http://benmccormick.org/2014/07/09/understanding-the-backbone-mindset-a-review-of-building-backbone-plugins-by-derick-bailey/&#34;&gt;full review&lt;/a&gt; if you&amp;rsquo;re interested, but I highly recommend it for any Backbone developer as a way of better understanding how to structure your Backbone applications.&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Alternative JavaScript</title>
      <link>https://benmccormick.org/2014/11/23/225800.html</link>
      <pubDate>Sun, 23 Nov 2014 23:58:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2014/11/24/225800.html</guid>
      <description>&lt;p&gt;It&amp;rsquo;s become a bit of a cliche that JavaScript is the &amp;ldquo;machine code of the web&amp;rdquo;. But now that mobile browsers have conclusively killed Flash, Silverlight and other &amp;ldquo;plugin languages&amp;rdquo;, JavaScript has become the only language that can reasonably claim to be &amp;ldquo;write once, run anywhere&amp;rdquo;.  That&amp;rsquo;s still a bit inflated though.  More accurately, you can use a subset of modern JavaScript that is compatible with the set of browsers and JavaScript environments that you want to support and run it in those places.  In practice this ends up being a version of JavaScript that matches the EcmaScript 5 spec &lt;sup id=&#34;fnref:0&#34;&gt;&lt;a href=&#34;#fn:0&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; for users who want to support modern browsers, or a very limited subset of the language that is somewhat similar to the ES3 spec for developers supporting old versions of Internet Explorer.  Because of the strange dynamic that the user rather than the developer of JavaScript code controls the language runtime that code uses, the JavaScript language has been forced to evolve slowly, with very few developers using the latest language features at any given time.  This, combined with a dislike of JavaScript from some developers has led to a proliferation of &amp;ldquo;compile to JavaScript&amp;rdquo; languages.&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s a problem with talking about &amp;ldquo;compile to JS&amp;rdquo; languages though.  That category groups 2 types of languages that are not especially similar.  The first type are languages that are completely different than JavaScript, which are then compiled down into JavaScript so that they can run in a web browser.  This is where the term &amp;ldquo;machine code of the web&amp;rdquo; really applies.  From the developer&amp;rsquo;s point of view, the fact that the code is compiled to JS is an implementation detail, and the JavaScript that is generated is likely to be unreadable, without any clear relation to the structure of the original code. Examples of this type of &amp;ldquo;compile to JS&amp;rdquo; language include new languages created for this purpose like &lt;a href=&#34;https://www.dartlang.org/&#34;&gt;Dart&lt;/a&gt; and &lt;a href=&#34;http://haxe.org/&#34;&gt;Haxe&lt;/a&gt;, as well as existing languages like &lt;a href=&#34;https://github.com/clojure/clojurescript&#34;&gt;Clojure&lt;/a&gt; and &lt;a href=&#34;http://www.gwtproject.org/&#34;&gt;Java&lt;/a&gt;.  The most extreme example of this has probably been &lt;a href=&#34;http://asmjs.org/&#34;&gt;ASM.js&lt;/a&gt; and &lt;a href=&#34;http://kripken.github.io/emscripten-site/&#34;&gt;emscripten&lt;/a&gt;, which together allow developers to compile C++ code to a subset of JavaScript that browsers can optimize for performance.  This type of language is great for developers who have a strong preference in language style, or an existing codebase that they want to port to the web.&lt;/p&gt;
&lt;p&gt;But there&amp;rsquo;s a second type of &amp;ldquo;compile to Javascript&amp;rdquo; language. These are languages that embrace the structure and semantics of JavaScript and focus on providing an alternative syntax that provides some benefit.  Benefits can include better code readability, cleaner syntax for common operations,  and support for modern JavaScript features that are not yet safe to use in common browsers without a compile step.  These languages will generally compile down to readable ES5 JavaScript that can easily be matched up 1 to 1 with the original source code.  They&amp;rsquo;re not intended to excuse you from learning JavaScript, instead they &amp;rsquo;re meant to smooth over the development process as you build JavaScript applications.  Examples of this second type of language include &lt;a href=&#34;http://coffeescript.org/&#34;&gt;CoffeeScript&lt;/a&gt;, &lt;a href=&#34;http://www.typescriptlang.org/&#34;&gt;TypeScript&lt;/a&gt;, &lt;a href=&#34;http://facebook.github.io/react/docs/jsx-in-depth.html&#34;&gt;JSX&lt;/a&gt;, &lt;a href=&#34;http://sweetjs.org/&#34;&gt;Sweet.js&lt;/a&gt;, and &lt;a href=&#34;https://github.com/google/traceur-compiler&#34;&gt;Traceur&lt;/a&gt;.  In this post I&amp;rsquo;m going to take a look at the strengths and weaknesses of some of these alternative Javascript syntaxes, and thinking through when it&amp;rsquo;s a good idea to use them.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ll start by standing up for the much maligned vanilla ES5 JavaScript syntax.  It has advantages.  It&amp;rsquo;s supported in many environments these days, including most browsers that people actually still use.  It has an incredible stable of tooling built up around it that allows for a smooth development experience.  And you can use it without jumping through any compile step hoops, or having to mentally translate the production code back to the source.  I&amp;rsquo;d argue that JavaScript sets a high bar for an alternate syntax to meet. Whether you agree or disagree with that, let&amp;rsquo;s at least admit that there is a bar and that the convenience of broad support and 1-1 mapping is an advantage that any alternative has to overcome.&lt;/p&gt;
&lt;p&gt;So what type of advantages can alternatives offer?  The different syntaxes I go through below all provide different strengths, but one mostly shared strength is that they allow you to start using some features of the newest version of JavaScript, EcmaScript 6.  ES6 brings a bunch of new features that make common development patterns easier, and looks to be a great improvement to the language.  By allowing you to take advantage of those features now, alternative syntaxes can speed up development and ease the transition into the new version of the language.  To get an idea of the more specific benefits an alternate syntax can bring, I&amp;rsquo;m going to go through 4 of the most popular syntaxes and explain why somebody would want to use them.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;coffeelogo.png&#34; alt=&#34;coffeescript logo&#34;&gt;&lt;/p&gt;
&lt;p&gt;CoffeeScript was the first alternative JavaScript syntax to gain popularity, and it is also one of the biggest breaks from the normal syntax.  Rewriting a simple Backbone view from the &lt;a href=&#34;http://todomvc.com/&#34;&gt;TodoMVC project&lt;/a&gt; in CoffeeScript would look something like this.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-coffeescript&#34; data-lang=&#34;coffeescript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; AppView &lt;span style=&#34;color:#ff79c6&#34;&gt;extends&lt;/span&gt; Backbone.View
    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;el: &lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;#todoapp&amp;#39;&lt;/span&gt;
    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;statsTemplate: &lt;/span&gt;_.template $(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;#stats-template&amp;#39;&lt;/span&gt;).html()
    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;events:
&lt;/span&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;&lt;/span&gt;        &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;keypress #new-todo&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;createOnEnter&amp;#39;&lt;/span&gt;
        &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;click #clear-completed&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;clearCompleted&amp;#39;&lt;/span&gt;
        &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;click #toggle-all&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;toggleAllComplete&amp;#39;&lt;/span&gt;

    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;initialize: &lt;/span&gt;&lt;span style=&#34;color:#50fa7b&#34;&gt;() =&amp;gt;&lt;/span&gt;
        &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;@allCheckbox = &lt;/span&gt;@$(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;#toggle-all&amp;#39;&lt;/span&gt;)[&lt;span style=&#34;color:#bd93f9&#34;&gt;0&lt;/span&gt;]
        &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;@$input = &lt;/span&gt;@$(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;#new-todo&amp;#39;&lt;/span&gt;)
        &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;@$footer = &lt;/span&gt;@$(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;#footer&amp;#39;&lt;/span&gt;)
        &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;@$main = &lt;/span&gt;@$(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;#main&amp;#39;&lt;/span&gt;)
        &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;@$list = &lt;/span&gt;$(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;#todo-list&amp;#39;&lt;/span&gt;)

        @listenTo(app.todos, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;add&amp;#39;&lt;/span&gt;, @addOne)
        @listenTo(app.todos, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;reset&amp;#39;&lt;/span&gt;, @addAll)
        @listenTo(app.todos, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;change:completed&amp;#39;&lt;/span&gt;, @filterOne)
        @listenTo(app.todos, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;filter&amp;#39;&lt;/span&gt;, @filterAll)
        @listenTo(app.todos, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;all&amp;#39;&lt;/span&gt;, @render)
        app.todos.fetch({&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;reset: &lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;true&lt;/span&gt;})

    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;render: &lt;/span&gt;&lt;span style=&#34;color:#50fa7b&#34;&gt;() =&amp;gt;&lt;/span&gt;
        &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;completed = &lt;/span&gt;app.todos.completed().length
        &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;remaining = &lt;/span&gt;app.todos.remaining().length

        &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; app.todos.length
            @$main.show()
            @$footer.show()

            @$footer.html @statsTemplate
                &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;completed: &lt;/span&gt;completed,
                &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;remaining: &lt;/span&gt;remaining

            &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;filter = &lt;/span&gt;app.TodoFilter &lt;span style=&#34;color:#ff79c6&#34;&gt;or&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;

            @$(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;#filters li a&amp;#39;&lt;/span&gt;)
                .removeClass &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;selected&amp;#39;&lt;/span&gt;
                .filter &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;[href=\&amp;#34;#/&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;#{&lt;/span&gt;filter&lt;span style=&#34;color:#f1fa8c&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;\&amp;#34;]&amp;#34;&lt;/span&gt;
                .addClass &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;selected&amp;#39;&lt;/span&gt;
        &lt;span style=&#34;color:#ff79c6&#34;&gt;else&lt;/span&gt;
            @$main.hide()
            @$footer.hide()

        &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;@allCheckbox.checked = &lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;!&lt;/span&gt;remaining

    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;addOne: &lt;/span&gt;&lt;span style=&#34;color:#50fa7b&#34;&gt;(todo) =&amp;gt;&lt;/span&gt;
        &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;view = &lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; TodoView
            &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;model: &lt;/span&gt;todo
        @$list.append view.render().el

    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;addAll: &lt;/span&gt;&lt;span style=&#34;color:#50fa7b&#34;&gt;() =&amp;gt;&lt;/span&gt;
        @$list.html &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;
        app.todos.each @addOne, @

   &lt;span style=&#34;color:#6272a4&#34;&gt;# ... and so on
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;As you can see, Coffeescript uses Ruby and Python style significant whitespace, which gives it a very different feel than JavaScript.  But it retains the language&amp;rsquo;s structure, giving it a low learning curve.  All of CoffeeScript&amp;rsquo;s built in structures compile down to ES3-compatible code, so anything you write in CoffeeScript will work in any modern JavaScript environment as long as you don&amp;rsquo;t use any incompatible APIs.&lt;/p&gt;
&lt;p&gt;Coffeescript gives you plenty of niceties to help you write faster and more succinct code.  In general it&amp;rsquo;s focused on taking common patterns and finding a short succinct way of representing them.  It removes some of the boilerplate from JavaScript code by replacing &lt;code&gt;function(){}&lt;/code&gt; and &lt;code&gt;this.&lt;/code&gt; with &lt;code&gt;() -&amp;gt;&lt;/code&gt; and &lt;code&gt;@&lt;/code&gt; respectively.  It&amp;rsquo;s a small change, but giving these common patterns easily recognizable shorthand saves plenty of characters across a code base.  These aren&amp;rsquo;t the only shorthands.  For instance it provides destructuring and string interpolation capabilities, allowing you to do things like this.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-coffeescript&#34; data-lang=&#34;coffeescript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;a = &lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;example&amp;#34;&lt;/span&gt;
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;b = &lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;This is an &lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;#{&lt;/span&gt;a&lt;span style=&#34;color:#f1fa8c&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;&lt;/span&gt;

[a, b] &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; [b,a]

&lt;span style=&#34;color:#6272a4&#34;&gt;# a ends up as &amp;#34;this is an example&amp;#34;, b is &amp;#34;example&amp;#34;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It&amp;rsquo;s easy to see that the EcmaScript 6 spec has been greatly influenced by CoffeeScript.  Features like classes, arrow functions, and splats/spreads are all parts of CoffeeScript that are going to be melded into the future of the language.  So why use it instead of something like Traceur which allows us to write ES6 code now?  The best answer I&amp;rsquo;ve seen was &lt;a href=&#34;https://github.com/raganwald-deprecated/homoiconic/blob/master/2011/12/jargon.md&#34;&gt;this short piece&lt;/a&gt; by Reg Brathwaite.  He argues that CoffeeScript is essentially a tool for writing good JavaScript.  The structure of the language encourages you to take advantage of JavaScript&amp;rsquo;s good parts, and the compilation process is able to encode many JavaScript best practices.  CoffeeScript features don&amp;rsquo;t add new capabilities to JavaScript, instead they encode accepted design patterns.&lt;/p&gt;
&lt;p&gt;In terms of tooling, CoffeeScript has been around a while, and has built up a good base of support in the JavaScript community.  It&amp;rsquo;s the recommended JavaScript syntax for Ruby on Rails projects and has wide support in the NodeJS community.  This community adoption means that many tools offer integrations for it.  You can also find some Coffeescript specific tooling.  For instance, there&amp;rsquo;s a &lt;a href=&#34;http://www.coffeelint.org/&#34;&gt;CoffeeLint&lt;/a&gt; tool that provides linting similar to JSHint.  CoffeeScript still doesn&amp;rsquo;t have the ecosystem that basic JavaScript enjoys in this area, but it has established itself enough that most common scenarios are addressed.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why use Coffeescript:&lt;/strong&gt; You like the transformed syntax, you want concise shorthand for common JavaScript design patterns, and you want to be able to write more readable code &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;typescriptlogo.png&#34; alt=&#34;TypeScript logo&#34;&gt;&lt;/p&gt;
&lt;p&gt;TypeScript is a language created by Microsoft to provide static type checking for JavaScript.  It allows you to annotate variables with types, then validates your code when it&amp;rsquo;s compiled into JavaScript. The benefits are pretty obvious.  Type checking forces you to think about the values that will get passed into functions and help you catch bad logic at compile time rather than runtime.   Static types also allow for smart intellisense-style completion.  As a Microsoft creation, this is fully supported in Visual Studio, but it&amp;rsquo;s also available in other IDES like WebStorm, and there&amp;rsquo;s some support for making it work in text editors like Vim and Sublime Text as well.&lt;/p&gt;
&lt;p&gt;Although TypeScript is primarily about types, it also provides some other niceties that fit with it&amp;rsquo;s theme of tools for building large JavaScript applications.  It provides classes that matches JavaScript&amp;rsquo;s ES6 class syntax, and modules that can compile down to AMD or CommonJS format.  You also can use ES6 lambda functions.&lt;/p&gt;
&lt;p&gt;Unlike CoffeeScript, TypeScript is unlikely to shorten your code.  Instead writing type definitions will likely lead to a larger code base, but one that&amp;rsquo;s easier to reason about in a given context.&lt;/p&gt;
&lt;p&gt;The TypeScript Hello World program from their site doesn&amp;rsquo;t look too much different than the original Javascript.  The important thing to note is the ability to use ES6 features as well as the type annotations on functions.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;
&lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; Greeter {
    constructor(&lt;span style=&#34;color:#ff79c6&#34;&gt;public&lt;/span&gt; greeting&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; string) { }
    greet() {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;&amp;lt;h1&amp;gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.greeting &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;&amp;lt;/h1&amp;gt;&amp;#34;&lt;/span&gt;;
    }
};
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; greeter &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; Greeter(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;Hello, world!&amp;#34;&lt;/span&gt;);
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; str &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; greeter.greet();
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;document&lt;/span&gt;.body.innerHTML &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; str;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;TypeScript was obviously built to be tool friendly, and if you&amp;rsquo;re using an IDE like Visual Studio or WebStorm, they&amp;rsquo;ll be able to take full advantage of that.  But the tooling around the text editors used by most JavaScript developers is less advanced.  There&amp;rsquo;s a nice &lt;a href=&#34;https://github.com/clausreinke/typescript-tools&#34;&gt;community effort&lt;/a&gt; to build a TypeScript server that text editors can plug into for completion information and other IDE functions, similar to the way that &lt;a href=&#34;http://ternjs.net/&#34;&gt;TernJS&lt;/a&gt; works.  But there&amp;rsquo;s none of the official support that Microsoft has built into Visual Studio, and the lack of attention shows.  Still, the compiler itself fills many of the roles that linting tools play for normal JavaScript, and many developers interested in type safety are probably already using an IDE style editor that will provide full support.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why Use TypeScript:&lt;/strong&gt; You want static type checking as well as the option to use some ES6 syntax now.  Also a great choice if you&amp;rsquo;re using an IDE and want better &amp;ldquo;intellisense&amp;rdquo; while writing code.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;sweetjslogo.png&#34; alt=&#34;Sweet.js logo&#34;&gt;&lt;/p&gt;
&lt;p&gt;Sweet.js is a very different animal than the other syntaxes I&amp;rsquo;m covering here.  Strictly speaking it&amp;rsquo;s not an alternative syntax at all.  It&amp;rsquo;s a toolkit to building your own your own alternate syntax.  You do that by defining &lt;em&gt;macros&lt;/em&gt;, which the compiler then loads and uses to transform your code.  For instance the example from &lt;a href=&#34;http://sweetjs.org/&#34;&gt;their website&lt;/a&gt; shows how you can define ES6 style classes in your code.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;// Define the class macro here...
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;macro &lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; {

  rule {

    $className {
        constructor $cparams $cbody
        $($mname $mparams $mbody) ...
    }

  } =&amp;gt; {

    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt; $className $cparams $cbody

    $($className.prototype.$mname
      &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt; $mname $mparams $mbody; ) ...

  }

}

&lt;span style=&#34;color:#6272a4&#34;&gt;// And now classes are in JavaScript!
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; Person {
  constructor(name) {
    &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.name &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; name;
  }

  say(msg) {
    console.log(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.name &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34; says: &amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; msg);
  }
}
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; bob &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; Person(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;Bob&amp;#34;&lt;/span&gt;);
bob.say(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;Macros are sweet!&amp;#34;&lt;/span&gt;);

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Sweet.js basically removes limits in terms of what your JavaScript syntax looks like.  If you can programatically define a syntax, you can use it.  And because Sweet.js macros are hygienic you can have confidence that you can use them without side effects.  This means that you can wipe away boilerplate, hiding it behind a new operator or keyword.  The modular nature of macros is also a big plus.  Rather than being locked into a syntax and set of capabilities &lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;, using macros allows you to mix and match the syntax you need.&lt;/p&gt;
&lt;p&gt;Relative to the other languages on this list though, Sweet.js lacks a lot of the benefits of a community standard. Any macros you write will only be documented to the extent you document them, and while you can run linting tools on the output, pretty much any other tooling out there, including basic stuff like syntax highlighting, is likely to be unable to parse the non-standard syntax created by macros.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why use Sweet.js:&lt;/strong&gt; You want your JavaScript syntax to work in a very specific way, and none of the existing options appeal to you, or you find yourself writing a lot of repetitive boilerplate that you can remove with a syntax change.&lt;/p&gt;
&lt;h3 id=&#34;traceur&#34;&gt;Traceur&lt;/h3&gt;
&lt;p&gt;The last alternate syntax that I&amp;rsquo;m going to be going in depth on is a bit different, because it&amp;rsquo;s technically just JavaScript syntax.  But it&amp;rsquo;s a form of JavaScript syntax that&amp;rsquo;s not supported everywhere yet.  &lt;a href=&#34;https://github.com/google/traceur-compiler&#34;&gt;Traceur&lt;/a&gt; is a project by Google that allows you to write code that&amp;rsquo;s valid in EcmaScript 6, and transpile it down into browser-compatible ES5 JavaScript.  Effectively it&amp;rsquo;s tomorrow&amp;rsquo;s JavaScript a bit early.  This has some obvious advantages.  First, it will eventually obsolete the compile step as all of the features of ES6 will be supported in browsers someday, and the changing world of browser release policies seem likely to make that sooner than you might expect.  Secondly, tools and other support around ES6 is shaping up nicely, and it&amp;rsquo;s guaranteed to get better, because this is just JavaScript.  It&amp;rsquo;s the future of the web platform.&lt;/p&gt;
&lt;p&gt;The case against using Traceur?  Besides the repeated themes of weaker tooling and an additional build step, Traceur simply doesn&amp;rsquo;t offer as much as the other syntaxes mentioned here.  It doesn&amp;rsquo;t significantly change the feel of the language like CoffeeScript, provide any clear new features like Typescript, or offer the flexibility of Sweet.js.  In the end it&amp;rsquo;s &amp;ldquo;just Javascript&amp;rdquo;, arriving a little bit early.  The question you need to answer is whether that&amp;rsquo;s enough to justify the compile step.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why use Traceur:&lt;/strong&gt; You like JavaScript but are frustrated by slow standards adoption.  You want to use the newest features of the language now while still supporting a variety of platforms.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; &lt;em&gt;Since I originally wrote this post, &lt;a href=&#34;babeljs.io&#34;&gt;Babel&lt;/a&gt; (formally 6to5) has exploded in usage and popularity as a tool for using future JavaScript features today. There are very good reasons for this.  It is much better documented than Traceur, supports more features, and generally aims to be a tool that people are using to build things, whereas Traceur has always felt like more of a tool for learning about the future of JavaScript.  I would highly recommend Babel for anyone looking to use future JavaScript features in their web projects.&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&#34;other-options&#34;&gt;Other Options&lt;/h3&gt;
&lt;p&gt;I chose to highlight the 4 syntaxes above because they&amp;rsquo;re the most popular general purpose alternate syntaxes for JavaScript.  But there are a few others worth mentioning here, for the sake of completeness if nothing else.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://facebook.github.io/react/docs/jsx-in-depth.html&#34;&gt;JSX&lt;/a&gt; is seemingly becoming quite popular as an extension to the JavaScript syntax, but I chose not to highlight it here because it is currently so tightly knit to &lt;a href=&#34;http://facebook.github.io/react/&#34;&gt;React&lt;/a&gt;.  While it is &lt;a href=&#34;http://blog.vjeux.com/2013/javascript/jsx-for-the-real-dom.html&#34;&gt;technically possible&lt;/a&gt; to use JSX for things other than React apps, in practice JSX has a limited enough scope &lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34;&gt;3&lt;/a&gt;&lt;/sup&gt; that there&amp;rsquo;s no real motivation to do so.  If you&amp;rsquo;re building a React application though, JSX is certainly worth exploring, as is the next syntax.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://flowtype.org/&#34;&gt;Flow&lt;/a&gt; is a new JavaScript syntax created by Facebook that uses the same type annotations as TypeScript, but does so in a way that aims to provide better type inference as well as supporting JSX.  I&amp;rsquo;m very interested to see where it goes, but for now it&amp;rsquo;s still early days as it was only announced &lt;a href=&#34;https://code.facebook.com/posts/1505962329687926/flow-a-new-static-type-checker-for-javascript/&#34;&gt;last week&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://docs.google.com/document/d/11YUzC-1d0V1-Q3V0fQ7KSit97HnZoKVygDxpWzEYW0U/edit&#34;&gt;AtScript&lt;/a&gt; also uses TypeScript&amp;rsquo;s type annotations, is mostly tied to a single framework, and in terms of public usage doesn&amp;rsquo;t really even exist yet &lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;.  So why is it worth a mention?  Because it is the syntax that AngularJS 2.0 is being developed in, and will be the first class &amp;ldquo;recommended syntax&amp;rdquo; for that framework when it is released next year.  Since Angular is currently the &lt;a href=&#34;http://www.google.com/trends/explore#q=AngularJS%2C%20BackboneJS%2C%20KnockoutJS%2C%20EmberJS%2C%20ReactJS&amp;amp;date=1%2F2012%2035m&amp;amp;cmpt=q&#34;&gt;most popular&lt;/a&gt; JavaScript MV* framework, that carries some weight and makes AtScript worth tracking, especially for Angular developers. But in today&amp;rsquo;s world it&amp;rsquo;s not a real contender to be used in a project.&lt;/p&gt;
&lt;h3 id=&#34;decisions&#34;&gt;Decisions&lt;/h3&gt;
&lt;p&gt;So how do you decide what JavaScript syntax to use?  My recommendation is to start by assuming ES5 JavaScript as a default.  Then examine any problems you&amp;rsquo;ve run into while using it.  Does your team struggle with JavaScript gotchas?  Has your project become large enough that a strong type system would provide more benefits than cost?  Do you really need some domain specific syntax to clean up your code?  Or are you happy and productive as is?  At that point you can decide whether a different syntax could help you get around those problems, or if the hassle of compilation steps and overhead of a new syntax would just end up making things worse.  You don&amp;rsquo;t want to use CoffeeScript or Traceur because they&amp;rsquo;re cool or different.  You&amp;rsquo;ll want to use them if they solve your problems.&lt;/p&gt;
&lt;h3 id=&#34;more-resources&#34;&gt;More Resources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;I linked to Reg Brathwaite&amp;rsquo;s &lt;a href=&#34;https://github.com/raganwald-deprecated/homoiconic/blob/master/2011/12/jargon.md&#34;&gt;CoffeeScript is not a language worth learning&lt;/a&gt; above, but I want to reiterate that it&amp;rsquo;s worth a read for anyone who&amp;rsquo;s interested in CoffeeScript, or who wants to understand why people would be excited to use it.&lt;/li&gt;
&lt;li&gt;Steve Sanderson&amp;rsquo;s vide on &lt;a href=&#34;http://vimeo.com/97519516&#34;&gt;Architecting large Single Page Applications with Knockout.js&lt;/a&gt; covers a lot of stuff and it&amp;rsquo;s worth watching the whole thing.  But if you skip to the 49:30 mark, he has a nice 10 minute discussion of TypeScript, his teams experience building a large application in it, and the pros and cons they found.&lt;/li&gt;
&lt;li&gt;I&amp;rsquo;m admittedly a bit skeptical about the value of Sweet.JS, but if you want to hear the case for it from somebody who really believes in it, take a look at this essay: &lt;a href=&#34;http://jlongster.com/Stop-Writing-JavaScript-Compilers--Make-Macros-Instead&#34;&gt;Stop Writing JavaScript Compilers! Make Macros Instead&lt;/a&gt;.  It does a great job of laying out the case for composable macros as an alternative to &amp;ldquo;monolithic&amp;rdquo; compilers.&lt;/li&gt;
&lt;li&gt;Finally, Axel Rauschmayer has a &lt;a href=&#34;http://www.2ality.com/2014/10/typed-javascript.html&#34;&gt;great roundup&lt;/a&gt; of the various languages looking to add type systems to JavaScript, diving pretty deep into each and clearly explaining the differences between TypeScript, Flow and AtScript.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;footnotes&#34;&gt;
&lt;ol&gt;
    &lt;li class=&#34;footnote&#34; id=&#34;fn:0&#34;&gt;
        &lt;p&gt;
        &lt;a href=&#34;http://en.wikipedia.org/wiki/ECMAScript&#34;&gt;EcmaScript&lt;/a&gt; is the &#34;official&#34; name for the JavaScript language as described in its specification.  EcmaScript 5 was the most recent finalized spec, published in December 2009. In practice though, JavaScript environements are never strict implementations of a specific spec.  Instead they gradually bring in features over time alongside the standards process.
        &lt;/p&gt;
        &lt;a href=&#34;#fnref:0&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li class=&#34;footnote&#34; id=&#34;fn:1&#34;&gt;
        &lt;p&gt;
        Yes readable is a &#34;beauty is in the eye of the beholder thing&#34;.  But readability is certainly a reason that many people are interested in CoffeeScript, and many of it&#39;s operators are designed as meaningful shorthand for operations that are more bloated in JavaScript.  While that  may present an initial readability barrier, in the long term it can make for a more to the point code base.
        &lt;/p&gt;
        &lt;a href=&#34;#fnref:1&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li class=&#34;footnote&#34; id=&#34;fn:2&#34;&gt;
        &lt;p&gt;
        For instance it&#39;s taken CoffeeScript a looong time to implement support for generators.
        &lt;/p&gt;
        &lt;a href=&#34;#fnref:2&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li class=&#34;footnote&#34; id=&#34;fn:3&#34;&gt;
        &lt;p&gt;
        Effectively all JSX does is allow for a convenient representation of the DOM within JavaScript.  While this is very important for React, and may be useful in some other cases, it does not provide the level of general purpose value of any of the other syntaxes mentioned in this article.
        &lt;/p&gt;
        &lt;a href=&#34;#fnref:3&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li class=&#34;footnote&#34; id=&#34;fn:4&#34;&gt;
        &lt;p&gt;
        You can use it and get it to compile by passing an option to Traceur, but as far as I know nobody is actually doing so yet outside of the Angular 2.0 team.
        &lt;/p&gt;
        &lt;a href=&#34;#fnref:4&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Underscore vs Lo-Dash</title>
      <link>https://benmccormick.org/2014/11/12/080000.html</link>
      <pubDate>Wed, 12 Nov 2014 09:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2014/11/12/080000.html</guid>
      <description>&lt;p&gt;Last week was the time for my team&amp;rsquo;s quarterly &amp;ldquo;dependency update&amp;rdquo; where we go through all the third party libraries we&amp;rsquo;re using and keep up on any updates or maintenance that need to happen.  That presented the opportunity for me to do a bit more research into an alternative for one of our libraries, &lt;a href=&#34;http://underscorejs.org/&#34;&gt;Underscore&lt;/a&gt;.  Underscore is a JavaScript utility library that provides helper functions for common idioms with a focus on functional programming.  It&amp;rsquo;s a dependency for &lt;a href=&#34;http://backbonejs.org/&#34;&gt;Backbone&lt;/a&gt;, the MVC library that our web app is based on, and was originally created by Jeremy Ashkenas, who also wrote Backbone.  I love the functional style that Underscore subscribes to, and while the much improved browser support for ES5 functions like map, reduce and filter makes it less necessary than it used to be, Underscore still provides plenty of benefits.&lt;/p&gt;
&lt;p&gt;For a while now though, I&amp;rsquo;ve been hearing about &lt;a href=&#34;https://lodash.com/&#34;&gt;Lo-Dash&lt;/a&gt;.  Lo-Dash began its life as a fork of Underscore, and still tracks Underscore&amp;rsquo;s API enough to allow it to serve as a drop-in replacement.  But under the hood it&amp;rsquo;s been completely rewritten, and it&amp;rsquo;s also added a number of features and functions that Underscore does not provide.  About a year ago I saw a spurt of articles recommending that Underscore users switch to Lo-Dash, and it came up again recently when &lt;a href=&#34;https://github.com/jashkenas/underscore/issues/1805&#34;&gt;Underscore&amp;rsquo;s decision to not follow semantic versioning&lt;/a&gt; caused problems for some NodeJS applications. The &lt;a href=&#34;http://stackoverflow.com/questions/13789618/differences-between-lodash-and-underscore&#34;&gt;definitive Stack Overflow question on the topic&lt;/a&gt; seems to come down pretty solidly in favor of Lo-Dash.  And the Lo-Dash &lt;a href=&#34;https://lodash.com/docs&#34;&gt;documentation&lt;/a&gt; touted a prettier chaining syntax as a feature, something that caught my eye since I&amp;rsquo;ve always disliked Underscore&amp;rsquo;s chaining mechanism.  As I did my research though I noticed that most of the comparisons are at least a year old.  Both libraries have continued to evolve and improve since then, so I thought there&amp;rsquo;d be value in adding another writeup comparing the current iterations.&lt;/p&gt;
&lt;h3 id=&#34;why-do-we-even-care&#34;&gt;Why Do We Even Care?&lt;/h3&gt;
&lt;p&gt;Before I get into the weeds of comparisons, let me address why you&amp;rsquo;d want to use either of these libraries at all.  Underscore and Lo-Dash provide cross-browser compatible functional programming utility methods.  This post will be long enough without me trying to explain all the benefits of functional programming, but suffice it to say that if you&amp;rsquo;re manipulating and transforming data in any reasonably complex way, an Underscore style library will help you write performant readable code easier than you could with what Javascript natively provides.  We&amp;rsquo;ll touch more on performance later, but both Underscore and Lo-Dash perform better than native browser functional methods, and for complex data manipulations they&amp;rsquo;re significantly more readable than a series of for loops.  They let you write code that&amp;rsquo;s fast and reads like a description of what you intend to have happen.&lt;/p&gt;
&lt;h3 id=&#34;how-are-underscore-and-lo-dash-similar&#34;&gt;How are Underscore and Lo-Dash similar?&lt;/h3&gt;
&lt;p&gt;As stated above, Underscore and Lo-Dash provide similar functionality.  Lo-Dash&amp;rsquo;s API is a superset of Underscore&amp;rsquo;s.  It provides everything that Underscore does, along with a few additional helper functions.  Lo-Dash can generally serve as a drop-in replacement for Underscore with no changes; it works just fine with Backbone.  So to some extent this question could be answered simply with a link to Underscore&amp;rsquo;s &lt;a href=&#34;http://underscorejs.org/&#34;&gt;documentation&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;how-are-underscore-and-lo-dash-different&#34;&gt;How are Underscore and Lo-Dash different?&lt;/h3&gt;
&lt;p&gt;This question could really be rephrased as &amp;ldquo;What has Lo-Dash added?&amp;rdquo;.  Lo-Dash answers that with a pretty extensive list on its site, but the claims really boils down to a few things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Usability Improvements&lt;/li&gt;
&lt;li&gt;Extra Functionality&lt;/li&gt;
&lt;li&gt;Performance Gains&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let&amp;rsquo;s examine those one by one.&lt;/p&gt;
&lt;h4 id=&#34;usability&#34;&gt;Usability&lt;/h4&gt;
&lt;p&gt;Lo-Dash makes a number of additions to Underscore that don&amp;rsquo;t add new capabilities, but increase usability for developers.  These include&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;del&gt;Built in Support for AMD Module Loaders&lt;/del&gt;&lt;/li&gt;
&lt;li&gt;Short hand syntaxes for chaining&lt;/li&gt;
&lt;li&gt;Custom Builds to only use what you need&lt;/li&gt;
&lt;li&gt;Semantic versioning and 100% code coverage&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Each of these are relatively small things that add up to time savings for developers.  &lt;del&gt;Supporting AMD natively saves a configuration step, allowing you to use Lo-Dash on requirejs-based projects without having to specify it as a shim.&lt;/del&gt; &lt;em&gt;(&lt;strong&gt;Update&lt;/strong&gt;: As of 1.6, Underscore also has native AMD support.)&lt;/em&gt;  Lo-Dash also improves the syntax for chaining functions.  Underscore&amp;rsquo;s chaining syntax has always felt a bit clunky to me.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt; getLongNames(users) {
    &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; _.chain(users).pluck(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;name&amp;#39;&lt;/span&gt;).filter(&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(name){
      &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt;  name.length &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;10&lt;/span&gt;;
    }).value();
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Lo-Dash cleans that up a bit by not requiring the chain functionality and instead making the Lo-Dash object a function, jQuery style:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt; getLongNames(users) {
    &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; _(users).pluck(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;name&amp;#39;&lt;/span&gt;).filter(&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(name){
      &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt;  name.length &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;10&lt;/span&gt;;
    }).value();
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It&amp;rsquo;s a small nicety that clears away some syntactical noise.&lt;/p&gt;
&lt;p&gt;Lo-Dash also provides custom builds.  By default Lo-Dash is significantly larger than Underscore.  The full library weighs in at 33KB minified, double Underscore&amp;rsquo;s 16KB size&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.  But you can negate that a bit by only pulling in the things you need.  The &amp;ldquo;modern version&amp;rdquo; that drops compatibility for IE8 and other older browsers weighs in at 29KB minified (but not gzipped).  If you want to drop the Lo-Dash extra functionality entirely, and only use it for performance and usability reasons, you can build an underscore compatible version and use only 20kb.  You can also go even further, and for instance use only the functionality required by Backbone.  That will get you down to 13kb, smaller than the original Underscore library.&lt;/p&gt;
&lt;p&gt;Finally, Lo-Dash provides semantic versioning and 100% code coverage.  To me these mostly serve as signals that this is a project interested in being disciplined about its engineering practices, which is a good sign.  But the semantic versioning issue seems to be particularly important for those using a utility library in Node, as Underscore&amp;rsquo;s versioning practices have &lt;a href=&#34;https://github.com/jashkenas/underscore/issues/1805&#34;&gt;caused problems&lt;/a&gt; for some.&lt;/p&gt;
&lt;h4 id=&#34;extra-functionality&#34;&gt;Extra Functionality&lt;/h4&gt;
&lt;p&gt;Lo-Dash includes several functions not included in Underscore.  Some of these are simply syntactical shortcuts for common idioms.  &lt;code&gt;_.forOwn&lt;/code&gt; allows you to iterate over an objects own properties, allowing you to skip the common practice of including a guard function in a loop to avoid touching items on an objects prototype chain.  Similarly &lt;code&gt;_.create&lt;/code&gt; is a simplified syntax for &lt;code&gt;Object.create&lt;/code&gt; and &lt;code&gt;_.parseInt&lt;/code&gt; is a safe version of the built-in parseInt function &lt;a href=&#34;http://stackoverflow.com/questions/14528397/strange-behavior-for-map-parseint&#34;&gt;which can have surprising behavior&lt;/a&gt;.  Lo-Dash also provides helper function for deep cloning, merging and extensions, operations that are not available in most libraries.  Specifically &lt;code&gt;_.cloneDeep&lt;/code&gt; and &lt;code&gt;_.merge&lt;/code&gt; serve as &amp;ldquo;deep&amp;rdquo; versions of Underscore&amp;rsquo;s &lt;code&gt;_.clone&lt;/code&gt; and &lt;code&gt;_.extend&lt;/code&gt;, and &lt;code&gt;_.where&lt;/code&gt; accepts an argument to support deep comparisons.  If you are routinely doing comparisons and copying of nested objects for equality, these functions will definitely have their place for you.&lt;/p&gt;
&lt;h4 id=&#34;performance&#34;&gt;Performance&lt;/h4&gt;
&lt;p&gt;Lo-Dash has an impressive set of &lt;a href=&#34;https://lodash.com/benchmarks&#34;&gt;benchmarks&lt;/a&gt; that you can run on its site which highlight its speed advantage over Underscore on a variety of operations. This is great, but benchmarking against specific tests like this can lead to local optimizations that might not lead to real-world speed.  I also don&amp;rsquo;t have much interest in many of the functions tested; I use them rarely and can handle a speed dip if necessary.  I was mostly interested in how Underscore and Lo-Dash compared on their core functional methods.  So I set up some jsPerf tests that you can run yourself for &lt;a href=&#34;http://jsperf.com/lodash-underscore-and-native-each&#34;&gt;_.each&lt;/a&gt;, &lt;a href=&#34;http://jsperf.com/lodash-underscore-and-native-contains&#34;&gt;_.contains&lt;/a&gt;, &lt;a href=&#34;http://jsperf.com/lodash-underscore-and-native-map&#34;&gt;_.map&lt;/a&gt;, &lt;a href=&#34;http://jsperf.com/lodash-underscore-and-native-reduce&#34;&gt;_.reduce&lt;/a&gt;, and &lt;a href=&#34;http://jsperf.com/lodash-underscore-and-native-filter&#34;&gt;_.filter&lt;/a&gt;. Here&amp;rsquo;s a simplified version of the results, comparing Underscore and Lo-Dash performance in terms of their improvement over the speed of the browsers&#39; native functions.  Results in the chart are averaged across browsers.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Edit: There used to be a chart here. Unfortunately the 3rd party service I used to embed the chart lost my data.  A good reminder to own your own content.  At this point the exact performance data from 2014 would no longer be representative of the current state of things anyway.  The tests above will provide a more accurate look at current performance.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;These tests are not incredibly scientific, and the chart especially is oversimplified, but they&amp;rsquo;re meant to represent real world usage in an easily digestible format.  Draw conclusions from them at your own risk.  That said, there were a few interesting results that I think are reasonably reliable.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Both Underscore and Lo-Dash blow away the native functional methods.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;With its latest versions Underscore has joined Lo-Dash in using loop based iteration to handle each, map, reduce and filter instead of proxying to the native code.  Counterintuitively this ends up being much faster.  Consistently across the board, Underscore and Lo-Dash beat native functions in terms of speed.  A little research indicates that this is because native functions optimize for sparse arrays and have more weird corner cases that they handle.  In any case, the performance difference is pretty startling across the board.&lt;/p&gt;
&lt;p&gt;You can still manage to beat the libraries&#39; performance by using simple for loops, which is what underscore and lo-dash use after they handle edge cases of their own.  The tradeoff at that point becomes about readability and reliability vs speed, and I&amp;rsquo;d suggest that using loops is an optimization step in most cases where you&amp;rsquo;d want to use a utility library, rather than a good starting point.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Lo-Dash is definitely not slower than Underscore&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s hard to know how significant some of the results here are, as there are a mix of differences which change across browsers.  Again, it&amp;rsquo;s not a very scientific test.  But Lo-Dash is never significantly slower than Underscore on pretty much any test (the worst seems to be a ~7% difference on Firefox for &lt;code&gt;_.each()&lt;/code&gt;).  And for several tests it came across as significantly faster (8x speed difference for contains on Firefox!).  I expect many of these differences would prove to be insignificant or inaccurate on a more rigorous test, but it would be very surprising if the net result was that Underscore was faster for common operations.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;summary-what-to-use&#34;&gt;Summary: What to use?&lt;/h3&gt;
&lt;p&gt;So to wrap it all up, if you need a utility library which one should you actually use?  I&amp;rsquo;ll stop just short of unreserved recommendations for Lo-Dash that I saw when I researched this.  I think Lo-Dash is the clear winner for NodeJS users.  Its biggest weakness (file size) doesn&amp;rsquo;t matter on the server, and its use of semantic versioning matters a lot more for developers depending on npm for dependency management.  So take the performance gains and extra capabilities and go with it.  However, there are more tradeoffs on the client.  Both Lo-Dash and Underscore are small, but optimizing page-weight still matters for many sites, especially on mobile devices.  Underscore has learned from Lo-Dash and improved its performance enough that the differences are often insignificant. And while Lo-Dash&amp;rsquo;s extras are convenient, none of them seem essential unless you are comparing and cloning a lot of deeply nested objects.  So I&amp;rsquo;d advise web developers to weigh the tradeoffs and pick the library that best meets their priorities.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;(&lt;strong&gt;Update:&lt;/strong&gt; There&amp;rsquo;s been plenty of discussion on this post today.  Check out the comments below for a lot of helpful insight from &lt;a href=&#34;https://twitter.com/jdalton&#34;&gt;John-David Dalton&lt;/a&gt;, Lo-Dash&amp;rsquo;s creator and an Underscore contributor.  You can also check out the discussion on &lt;a href=&#34;http://www.reddit.com/r/javascript/comments/2m2hs6/underscore_vs_lodash/&#34;&gt;Reddit&lt;/a&gt;.)&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&#34;more-resources&#34;&gt;More Resources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;http://kitcambridge.be/blog/say-hello-to-lo-dash/&#34;&gt;Say Hello to Lo-Dash&lt;/a&gt;, a blog post written by Lo-Dash&amp;rsquo;s core team after they released 1.0 is a great summary of the advantages of Lo-Dash.  It&amp;rsquo;s a year and a half old now, but mostly holds up pretty well, with the only real difference being that Underscore has pulled in several of the features they mention here since then.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;I mentioned this in the post, but Lo-Dash provides a much more thorough benchmarking page than what I provided &lt;a href=&#34;https://lodash.com/benchmarks&#34;&gt;on their site&lt;/a&gt;.  They also provide a helpful &lt;a href=&#34;https://github.com/lodash/lodash/wiki/Roadmap&#34;&gt;roadmap&lt;/a&gt; to let users know about plans for Lo-Dash 3.0.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;footnotes&#34;&gt;
&lt;ol&gt;
    &lt;li class=&#34;footnote&#34; id=&#34;fn:1&#34;&gt;
        &lt;p&gt;
        These numbers are minified but not gzipped, based on the file size when I download the minified versions from the project site.
        &lt;a href=&#34;#fnref:1&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Vim Workflows: File Switching</title>
      <link>https://benmccormick.org/2014/11/09/230652.html</link>
      <pubDate>Mon, 10 Nov 2014 00:06:52 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2014/11/10/230652.html</guid>
      <description>&lt;p&gt;Becoming productive in Vim is about more than just knowing all of the features available to you&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;. It&amp;rsquo;s all about knowing which ones to use in which situations.  In my series from this summer on &lt;a href=&#34;http://benmccormick.org/learning-vim-in-2014/&#34;&gt;learning Vim&lt;/a&gt;, I focused a lot on the different tools Vim provides for solving problems.  Today I&amp;rsquo;ll show how I put some of those tools together to actually be more productive.&lt;/p&gt;
&lt;p&gt;A good tool should allow you to focus on your problem while using it, without making you spend a lot of time thinking about extraneous things. File switching is an area in text editing that can really slow you down if you let it.  The first file switching method that most Vim users is the simple &lt;code&gt;:e&lt;/code&gt; command to open a file.  Technically it&amp;rsquo;s the only command you need for file switching, since you can use it to open up any file you want and start editing it.  But doing so requires you to essentially internalize the complete structure of your file system and type out full paths every time.  On a large project with nested directories that becomes a significant mental load and use of time, even if you&amp;rsquo;re taking advantage of Vim&amp;rsquo;s tab completion features. And it&amp;rsquo;s a mental load that&amp;rsquo;s inessential to the task at hand.  You need to recall the precise layout of your file structure every time only because the tool isn&amp;rsquo;t able to make things easier for you.&lt;/p&gt;
&lt;p&gt;Fortunately Vim is able to make easier things easier for you when you use the right tool for the job.  That means rather than using one file switching strategy to rule them all, we can combine several tools to reduce the mental load on us and focus on our code or writing. I&amp;rsquo;ll specifically look at a few common scenarios and my approach for each.  This isn&amp;rsquo;t the only workflow you can use to address these scenarios, but hopefully it will inspire you to improve your own Vim workflow.  So here are the different scenarios:&lt;/p&gt;
&lt;h4 id=&#34;i-want-to-move-to-a-file-with-a-name-i-know&#34;&gt;I want to move to a file with a name I know&lt;/h4&gt;
&lt;img src=&#34;ctrlp&#34; class=&#34;full-width&#34; alt =&#34;ctrlp screenshot&#34;&gt;
&lt;p&gt;When you&amp;rsquo;re moving to a file with a name that you know, it&amp;rsquo;s hard to beat the power of a fuzzy finding plugin like &lt;a href=&#34;https://github.com/kien/ctrlp.vim&#34;&gt;CtrlP&lt;/a&gt; or &lt;a href=&#34;https://github.com/Shougo/unite.vim&#34;&gt;Unite&lt;/a&gt;.  CtrlP allows me to type in the name of a file without remembering or typing a long directory path and instantly get a list of potential files.  Usually the file I&amp;rsquo;m looking for is the top hit.&lt;/p&gt;
&lt;h4 id=&#34;i-want-to-move-to-a-file-but-i-dont-know-what-its-called&#34;&gt;I want to move to a file, but I don&amp;rsquo;t know what it&amp;rsquo;s called&lt;/h4&gt;
&lt;img src=&#34;nerdtree.png&#34; class=&#34;full-width&#34; alt =&#34;NerdTree screenshot&#34;&gt;
&lt;p&gt;This scenario happens most often on projects that you&amp;rsquo;re unfamiliar with and just getting into.  You&amp;rsquo;re looking for some functionality, but don&amp;rsquo;t know exactly what it&amp;rsquo;s called within the project and need to look through the file system for hints.  In this case you need a directory browsing tool.  Vim bundles &lt;a href=&#34;http://www.vim.org/scripts/script.php?script_id=1075&#34;&gt;netrw&lt;/a&gt; by default and it&amp;rsquo;s a good starting place.  If you have issues with netrw, many people install &lt;a href=&#34;https://github.com/scrooloose/nerdtree&#34;&gt;NerdTree&lt;/a&gt; as an alternative file explorer.  I personally don&amp;rsquo;t use NerdTree very often these days.  Most of my work over the last year or so has been on one large project or smaller experimental projects and I haven&amp;rsquo;t needed it.  But it&amp;rsquo;s been very useful when I&amp;rsquo;ve cloned down a github repository to look it over or make changes.  It&amp;rsquo;s the best way to quickly get the lay of the land of a project within Vim, and to find a specific file before you really know what you&amp;rsquo;re looking for.&lt;/p&gt;
&lt;h4 id=&#34;i-want-to-move-to-a-file-that-i-already-have-open&#34;&gt;I want to move to a file that I already have open&lt;/h4&gt;
&lt;img src=&#34;bufferlist.png&#34; class=&#34;full-width&#34; alt =&#34;Buffer list&#34;&gt;
&lt;p&gt;A common scenario in Vim involves moving back and forth between 2 files, possibly a file and its corresponding test file.  If you don&amp;rsquo;t want to use splits, that means you&amp;rsquo;ll want a quick command to move between open files.  Fortunately Vim keeps a list of active buffers open.  When I&amp;rsquo;m only flipping between 2 files I&amp;rsquo;ll usually use the &lt;code&gt;:bprev&lt;/code&gt; and &lt;code&gt;:bnext&lt;/code&gt; commands, which I&amp;rsquo;ve aliased to &lt;code&gt;[b&lt;/code&gt; and &lt;code&gt;]b&lt;/code&gt; &lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;. If I have more than a few files open though I&amp;rsquo;ll usually either use &lt;code&gt;:b&lt;/code&gt; and type the name of the file, or just use ctrlp again, which doesn&amp;rsquo;t require me to remember if the file I wasn&amp;rsquo;t is actually already open or not.&lt;/p&gt;
&lt;h4 id=&#34;i-want-to-move-back-to-the-place-i-just-was&#34;&gt;I want to move back to the place I just was&lt;/h4&gt;
&lt;img src=&#34;indy.jpg&#34; class=&#34;full-width&#34; alt =&#34;indy&#34;&gt;
&lt;p&gt;&amp;ldquo;Rabbit Holing&amp;rdquo; happens to me all the time when I&amp;rsquo;m working on code.  I start looking at one thing, then look at code related to that, and before I know it I&amp;rsquo;m 4 files deep following a chain of stuff I&amp;rsquo;m debugging.  Oftentime I want to move back up that chain.  I could of course remember what files I opened and use one of the methods above, but that requires me to internalize the memory of events.  The command that maps best to my desire to move back up the chain is using Vim&amp;rsquo;s jumplist.  Vim keeps track of every &amp;ldquo;jump&amp;rdquo; you make within a window or split, and allows you to move back up and down that jump list as you like, both within files and across them. The commands to move up and down the jump list are mapped to &lt;code&gt;&amp;lt;c-o&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;c-i&amp;gt;&lt;/code&gt; by default.  When I use them I don&amp;rsquo;t have to keep track of what files I&amp;rsquo;m moving across or even if I&amp;rsquo;m switching files at all.  I can just investigate my issue and have confidence that I&amp;rsquo;ll be able to get back.  Think of it as tying down a rope before you dive into a cave full of snakes.&lt;/p&gt;
&lt;h4 id=&#34;i-want-to-create-a-new-file&#34;&gt;I want to create a new file&lt;/h4&gt;
&lt;p&gt;Creating a new file means that we finally find a use for the basic &lt;code&gt;:e&lt;/code&gt; command.  Because you need to specify a full directory path anyway when you&amp;rsquo;re creating a file, it makes sense to use the basic Vim commands here.  If you need to create a directory to put the file in, you can use the shell command with &lt;code&gt;:!mkdir &amp;lt;path/to/dir&amp;gt;&lt;/code&gt;.  While writing this piece I learned that ctrlp has the ability to create a new directory path and file in a single command, which is a nice touch.  But you lose out on Vim&amp;rsquo;s autocompletion of paths if you&amp;rsquo;re creating a directory nested in existing directories.  I find the builtins to be simplest here.&lt;/p&gt;
&lt;h4 id=&#34;i-want-to-edit-a-specific-piece-of-code-but-dont-know-what-file-its-in&#34;&gt;I want to edit a specific piece of code, but don&amp;rsquo;t know what file it&amp;rsquo;s in&lt;/h4&gt;
&lt;img src=&#34;agvim.png&#34; class=&#34;full-width&#34; alt =&#34;Ag.vim&#34;&gt;
&lt;p&gt;Finally, possibly the most common scenario for me is when I know I have a particular piece of code I need to edit, but don&amp;rsquo;t have it mapped to a particular file in my head.  Rather than forcing myself to recall the file, the easiest path is to let Vim take the information I know and help me out.  Specifically I use Ag.vim for code search within projects.  It is a wrapper around Ag, a &lt;a href=&#34;http://benmccormick.org/2013/11/25/a-look-at-ack/&#34;&gt;fantastic code search program based on Ack&lt;/a&gt;.  It allows me to enter a search term, and then pulls up all occurrences of that term within my project.  One of it&amp;rsquo;s best features is filtering by file type, which allows me to type something like &lt;code&gt;:Ag --less &amp;quot;\.widget&amp;quot;&lt;/code&gt; and search my LESS files for all rules effecting the class &lt;code&gt;.widget&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&#34;let-vim-work-for-you&#34;&gt;Let Vim Work For You&lt;/h3&gt;
&lt;p&gt;The workflow I described is not the &amp;ldquo;one true way&amp;rdquo; to navigate files in Vim.  Some people hate plugins and will prefer to use &lt;code&gt;:e&lt;/code&gt;,&lt;code&gt;:b&lt;/code&gt;, and netrw for everything. You can certainly do many of the things above with NerdTree or CtrlP if you prefer to simplify to one tool.  And &lt;a href=&#34;https://github.com/Shougo/unite.vim&#34;&gt;Unite&lt;/a&gt; is an attempt to pull almost all of these scenarios into one tool.  The point is to be aware of the inessential work created in the different scenarios you face when coding and offload the work to Vim in a way that makes sense to you.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&#34;more-resources&#34;&gt;More Resources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;http://vimcasts.org/blog/2013/01/oil-and-vinegar-split-windows-and-project-drawer/&#34;&gt;Oil and Vinegar&lt;/a&gt; is a nice Vimcasts article on how to make NerdTree work well with multiple splits&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;I wrote a more &lt;a href=&#34;http://benmccormick.org/2014/07/07/learning-vim-in-2014-working-with-files/&#34;&gt;introductory post&lt;/a&gt; this summer on the tools you can use to manage files in Vim.  It talks in a bit more detail about some of the Vim features I mentioned above.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;footnotes&#34;&gt;
&lt;ol&gt;
    &lt;li class=&#34;footnote&#34; id=&#34;fn:1&#34;&gt;
        &lt;p&gt;
        That&#39;s true of many things actually.  
        &lt;/p&gt;
        &lt;a href=&#34;#fnref:1&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li class=&#34;footnote&#34; id=&#34;fn:2&#34;&gt;
        &lt;p&gt;
        I actually use &lt;a href=&#34;https://github.com/tpope/vim-unimpaired&#34;&gt;unimpared.vim&lt;/a&gt; to provide consistent keybindings for these types of motions.
        &lt;/p&gt;
        &lt;a href=&#34;#fnref:2&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Thoughts on Angular 2.0</title>
      <link>https://benmccormick.org/2014/11/08/142409.html</link>
      <pubDate>Sat, 08 Nov 2014 15:24:09 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2014/11/08/142409.html</guid>
      <description>&lt;p&gt;Rob Eisenberg has a pretty incredible rundown of the current Angular 2.0 proposal and the thought process behind it &lt;a href=&#34;http://eisenbergeffect.bluespire.com/all-about-angular-2-0/&#34;&gt;on his blog&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Given Angular&amp;rsquo;s design origins in combination with the changing web and general computing landscape, it&amp;rsquo;s pretty clear that some changes are needed. In fact, without starting to address these issues now, Angular runs the risk of being obsolete within a year&amp;rsquo;s time. A framework that cannot work with Web Components, bogs down on mobile or continues to push its own module and class API against the standards, is not going to last long. The Angular team&amp;rsquo;s answer to these problems is a new version: Angular 2.0. It is essentially a re-imagining of AngularJS for the modern web, taking into account everything that has been learned over the last five years.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;He describes in detail the various challenges that the Angular team has faced in keeping the current version modern, the justification for a drastic breaking change, and provides a fascinating look at the inner debates and thought process that produced the current controversial proposal. It&amp;rsquo;s long, but well worth reading for any Angular developer or anybody interested in the near future changes coming to the web platform.  The trends he identifies here are going to effect every library and framework out there, and it will be interesting to see how they respond.&lt;/p&gt;
&lt;p&gt;As for Angular&amp;rsquo;s specific response, it&amp;rsquo;s a bit hard not to see their approach as throwing their hands up in the air, giving up and building something new, but keeping the name.  Rob (a recently added member of the core team) even calls them out on this to a certain extent.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Even though I haven&amp;rsquo;t got to the details yet, you can probably tell that AngularJS 2.0 is quite different from 1.x. One might ask if it&amp;rsquo;s even the same framework. I think that&amp;rsquo;s a good question. As I&amp;rsquo;ve mentioned earlier, I think the Angular team needs to shoulder the burden of providing a concrete timeline for 1.x support, a migration path to 2.0 and some guidance for companies making decisions today or who would like to plan in advance for 2.0. These are not particularly exciting tasks for the technically-minded Angular team, but I think they are necessary, helpful and respectful to the community.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If you haven&amp;rsquo;t yet seen the changes coming in Angular 2.0, the tl;dr version is that everything has changed.  Syntax is different across the board, not just at a micro level but also at the structural level.  Several of the key concepts that Angular developers have had to learn including controllers, scope, and 2 way binding are either definitely gone, still being debated, or changed beyond recognition.  And the core concepts of modules, dependency injection and directives have all had major compatibility breaking syntax changes.  Keeping the Angular name seems to be more a matter of the new project sharing a general philosophy and set of maintainers with the old project rather than a suggestion that this is simply a large iteration on an existing framework.&lt;/p&gt;
&lt;p&gt;A few more assorted thoughts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;I really appreciated the listing of the challenges Angular is facing at the beginning. From my outsider perspective (I&amp;rsquo;m a web developer but have not spent a lot of time with Angular recently), it seems like they&amp;rsquo;ve nailed the first step of asking the right questions.  Any framework that isn&amp;rsquo;t optimized for mobile browsers or doesn&amp;rsquo;t integrate with ES6 classes and modules is likely to look silly in a few years.  And while web components are still not a sure thing, they&amp;rsquo;re rapidly &lt;a href=&#34;http://benmccormick.org/2014/08/07/component-based-development/&#34;&gt;becoming a standard for reusable code on the web&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Creating a custom JS preprocessor to support the framework you&amp;rsquo;re building is starting to look like a trend.  And that is not a good thing.  I was not a fan of React bundling JSX, and Angular 2.0&amp;rsquo;s use of AtScript seems to be equally unfortunate.  In both cases the language is not required to use the framework, but instead is treated as a &amp;ldquo;First Class&amp;rdquo; language used as an escape hatch to smooth over rough patches in their API.  At least JSX is a spec, even if it&amp;rsquo;s a very React centric one.  AtScript appears to be a Google only thing at the moment, inspired by but incompatible with Typescript.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The next time I hear a developer claim that marketing is worthless, I&amp;rsquo;m going to bring up the last few weeks in the JavaScript framework world.  Angular announced their 2.0 plans for the world in a presentation that many people saw only as a &lt;a href=&#34;https://docs.google.com/presentation/d/1XQP0_NTzCUcFweauLlkZpbbhNVYbYy156oD--KLmXsk/preview?utm_content=bufferf1174&amp;amp;utm_medium=social&amp;amp;utm_source=twitter.com&amp;amp;utm_campaign=buffer&amp;amp;slide=id.p&#34;&gt;set of slides filled with tombstones&lt;/a&gt;.  By focusing (at least on the slides) on the things being lost and the drastic changes to syntax, the online conversation focused on the compatibility problems with the release, rather than the problems it would solve.  Now we finally have a detailed explanation of why these breaking changes are happening, but it&amp;rsquo;s in the form of an opinionated blog post that emphasizes the current uncertainty around the project.  Angular seems to have found an awkward middle ground between involving the community from the beginning and releasing a polished product, where they&amp;rsquo;ve introduced a &amp;ldquo;not quite ready&amp;rdquo; concept to the world.&lt;/p&gt;
&lt;p&gt;Contrast that to the &lt;a href=&#34;http://emberjs.com/&#34;&gt;EmberJS&lt;/a&gt; team, which has pretty transparently taken advantage of the marketing confusion around Angular in order to double down on a message of &amp;ldquo;stability without stagnation.  Their &lt;a href=&#34;https://github.com/emberjs/rfcs/pull/15&#34;&gt;Ember 2.0 RFC&lt;/a&gt; is clearly informed by the reception to Angular&amp;rsquo;s plans, especially the 2nd paragraph.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This is not a big-bang rewrite; we will continue development on the master branch, and roll out changes incrementally on the 1.x release train. The 2.0.0 release will simply remove features that have been deprecated between now and then. Our goal is that you can move your Ember app to 2.0 incrementally, one sprint at a time.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Ember and Angular are facing roughly the same challenges in terms of deprecating old syntax and adapting to changes in the web platform.  Regardless of what you think of their different approaches, by clearly articulating their plans in a united way before they begin actually writing the code to accomplish them, Ember is winning the marketing battle here by a mile.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Related to all of the above, it&amp;rsquo;s hard to recommend starting a new Angular project to anyone right now.  While the 1.x branch will continue to receive support going forward if for no other reason than the number of people currently using it, the issues that 2.0 is trying to solve are real and will make it harder for 1.0 to keep up with the rest of the web as it goes forward.  This is not a Python 2/3 situation where Python 2 still remains a viable language to start a project with 6 years later.  Because the web platform will continue shifting under the code, a language that doesn&amp;rsquo;t support modern idioms will quickly begin to fall behind alternatives.  It&amp;rsquo;s very possible that Angular 2.0 will regain Angular 1.x&amp;rsquo;s current spot as the most popular MVC framework on the web, but until it&amp;rsquo;s released or the core team can show a clear migration path from 1.x to 2.0, Angular development is going to look like a dead end road.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>A Quick Review Of Google Inbox</title>
      <link>https://benmccormick.org/2014/11/03/224530.html</link>
      <pubDate>Mon, 03 Nov 2014 23:45:30 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2014/11/04/224530.html</guid>
      <description>&lt;p&gt;Google announced their new email product, &lt;a href=&#34;http://www.google.com/inbox/?gclid=CNqBxtSE28ECFQMT7AodrBYAVQ&#34;&gt;Google Inbox&lt;/a&gt; last week, and I was able to get a Day 1 invitation from a friend at Google.  I&amp;rsquo;ve been using it for my personal email account since then.  A few people have asked me about it, so I thought I&amp;rsquo;d write up my impressions so far.&lt;/p&gt;
&lt;p&gt;I think it&amp;rsquo;s important to start by making it clear what Inbox is, because it seems like there&amp;rsquo;s a lot of confusion out there.  Inbox is an alternative view to your existing Gmail account.  It is not a new webmail account, and it is not a generic mail client &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.  Changes that are made in Inbox are reflected in Gmail and vice versa.  Inbox is a &amp;ldquo;fresh coat of paint&amp;rdquo; with some add-on features, not a &amp;ldquo;whole new thing&amp;rdquo;.  You can access the Inbox interface on the web at &lt;a href=&#34;http://inbox.google.com&#34;&gt;inbox.google.com&lt;/a&gt;, or through apps for iOS and Android.  This review is primarily of the web interface, since I prefer to deal with my work and personal email through a single app on my phone, and that&amp;rsquo;s not yet possible with Inbox.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;sidebyside.png&#34; alt=&#34;Inbox and Mailbox&#34;&gt;&lt;/p&gt;
&lt;p&gt;Using Inbox for the first time was a little bit of deja vu.  Google seems to have borrowed heavily from &lt;a href=&#34;http://www.mailboxapp.com/&#34;&gt;Mailbox&lt;/a&gt;, my current iPhone email app of choice.  The interface is heavily simplified compared to the a traditional mail client like Gmail or Outlook.  It relies heavily on the &amp;ldquo;To-Do&amp;rdquo; list metaphor that several modern clients like Mailbox and &lt;a href=&#34;http://www.dispatchapp.net/&#34;&gt;Dispatch&lt;/a&gt; have popularized.  So instead of archiving or deleting messages, you mark them done, and if you aren&amp;rsquo;t ready to deal with a particular email yet, you can &amp;ldquo;pin it&amp;rdquo; in your inbox, or set a reminder to bring it back up later.  Other than pinning&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; , this format maps pretty well to how I deal with email in general, and is almost exactly Mailbox&amp;rsquo;s workflow, so at least for me it felt natural. Like Mailbox, Inbox is opionionated software. It&amp;rsquo;s optimized for triaging and processing email quickly.  If you spend more time composing emails than reading them, you&amp;rsquo;ll probably find Inbox lacking in terms of compose tools.  But for the majority of us who are just trying to keep our heads above the email ocean, this type of streamlined workflow saves a lot of time.&lt;/p&gt;
&lt;p&gt;Inbox&amp;rsquo;s biggest innovation is its &amp;ldquo;bundles&amp;rdquo; concept.  Bundles are the next generation of Gmail&amp;rsquo;s label system, and roughly map to labels when moving back and forth between Gmail and Inbox.  They&amp;rsquo;re a standardized interface for the way I used labels to organize things anyway.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;skiptheinbox.png&#34; alt=&#34;Here&amp;rsquo;s what your labels look like&#34;&gt;&lt;/p&gt;
&lt;p&gt;In Gmail, I&amp;rsquo;ve set up a bunch of rules that apply a label to emails that meet a criteria, then have it skip the inbox.  This has the effect of being able to show things like unread updates from a social network as numbers on the left side of the screen, without cluttering my inbox.  I like that system in Gmail, but it has always been annoying that I can&amp;rsquo;t easily see those numbers anywhere except the Gmail web interface.  On my phone, those labels/folders are hidden away unless I dig down for them.  With Inbox, I can change that rule to just apply the label without moving to the inbox, and then make that label a &amp;ldquo;bundle&amp;rdquo;.  When I do that, those emails show up as grouped within my inbox, taking up minimal space.  It&amp;rsquo;s easy to skim past them, or to bulk archive them if necessary.  Apparently I&amp;rsquo;m not the only one who&amp;rsquo;s hacked this feature in on their own before, because Inbox contains a category of labels in its sidebar marked as &amp;ldquo;skipped the inbox&amp;rdquo;, where it puts any labels set up as I&amp;rsquo;ve described.  Inbox lets you convert these labels to bundles in one click, meaning you don&amp;rsquo;t actually have to go into Gmail and change the rules.  This has been nice for my personal email, I expect it to be amazing for my work email if/when Google Apps starts supporting the Inbox interface.  I get a lot of automated status/notification style emails for work, which I currently tend to auto-archive without reading.  For the most part this is fine, but for messages that indicate warnings of some type, I&amp;rsquo;d love to be able to see the count of current warnings in my inbox, with the option to bulk-delete with a click.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;smalldelights.png&#34; alt=&#34;The compose feature is very slick&#34;&gt;&lt;/p&gt;
&lt;p&gt;Other than Bundles, Inbox&amp;rsquo;s other features can all clearly be traced back to Gmail or the new wave of to-do style mail clients.  The compose window and email viewing screen will both feel familiar to anyone used to Gmail&amp;rsquo;s current interface, albeit a bit stripped down and simplified.  The compose button has the nice touch of showing the last few people you&amp;rsquo;ve emailed as default options to receive your new message.  Reminders is a Mailbox feature that I&amp;rsquo;ve never used much, but Inbox steps it up a bit by allowing you to enter your own reminders without an existing email (much better than sending yourself an email), and by integrating Google Now style intelligence, for instance including directions to the restaurant when it reminds you about a dinner. I still don&amp;rsquo;t expect to get much use out of it personally, since I like my todos to get out of the email client to a more permanent resting place, but for those who use the inbox as their todo manager, it looks pretty slick.&lt;/p&gt;
&lt;p&gt;One more praise: Inbox&amp;rsquo;s interface is simple, but avoids the mistake Mailbox makes of going too far down that road.  Mailbox doesn&amp;rsquo;t allow you to filter by label and de-emphasizes the &amp;ldquo;sent from&amp;rdquo; email, 2 attempts to simplify the interface that have caused me grief in the past.  Inbox avoids both those pitfalls while still removing a lot of clutter from the crowded Gmail interface.  My one complaint in this area is that chat received the short end of the stick in Inbox.  It&amp;rsquo;s tucked up into the header bar by default, with no quick visual cue as to who is currently online.  Since I began writing this post, I&amp;rsquo;ve discovered it&amp;rsquo;s possible to pin a contact list to the right side of the screen, which makes me quite happy.  That&amp;rsquo;s not at all obvious or discoverable though, and the default is a huge step down from classic Gmail&amp;rsquo;s wonderful in-browser chat interface.&lt;/p&gt;
&lt;p&gt;Of course the reason that Inbox can be simple is that it is &amp;ldquo;just Gmail&amp;rdquo;.  It ignores a lot of complex configuration that you&amp;rsquo;d want in an email client, and in doing so simplifies the UI.  There&amp;rsquo;s no rules editor for handling different types of mail beyond the built-in intelligent bundles, and no ability to handle things like email forwarding or aliases as far as I&amp;rsquo;ve seen.  It offloads that complicated stuff to the classic Gmail interface.  That fact allows Inbox to be simple and clear for less sophisticated users, while still allowing power users a backdoor to customize, but it does mean that Inbox is an addition to, not a replacement for Gmail, at least for now.&lt;/p&gt;
&lt;p&gt;Inbox is an extremely impressive piece of UI design.  It&amp;rsquo;s the first major app to feature Google&amp;rsquo;s  new Material Design style, and if this is the type of imaginative rethinking that we&amp;rsquo;ll get from Google&amp;rsquo;s design teams going forward, I&amp;rsquo;m excited to see more.  My only real complaints at this point are the lack of support for Google Apps, something I&amp;rsquo;m sure will be rectified in the future, and the fact that, like Mailbox, it&amp;rsquo;s design encourages users to treat the inbox as a long term todo list, rather than a triaging area.  I don&amp;rsquo;t expect that second issue to be fixed, it&amp;rsquo;s ingrained right down to the name of the application.  But since there isn&amp;rsquo;t currently a better option on that front, I will happily enjoy Inbox&amp;rsquo;s simplicity and nice design touches.  It has already replaced the default Gmail interface for me as my desktop mail client, and I expect it to replace Mailbox on my phone as soon as it supports Google Apps.  If Inbox sounds interesting to you I definitely recommend finding a friend with an invite and checking it out.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34;&gt;
&lt;ol&gt;
    &lt;li class=&#34;footnote&#34; id=&#34;fn:1&#34;&gt;
        &lt;p&gt;
        I&#39;ve seen some speculation that Inbox might eventually support clients other than Gmail to allow Google to gather data on email outside their ecosystem, but I highly doubt it.  Inbox is built on Gmail&#39;s proprietary concepts, and trying to pull things like reminders off without controlling the backend servers would be hacky at the very least.
        &lt;/p&gt;
        &lt;a href=&#34;#fnref:1&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li class=&#34;footnote&#34; id=&#34;fn:2&#34;&gt;
        &lt;p&gt;
        I don&#39;t want my inbox to be a long term to do list (which is what pinning seems to be for).  The to do metaphor is more helpful as a triaging tool, to split email into &#34;ignore&#34;, &#34;handle now&#34;, and do later.  If I&#39;m ignoring or replying right away, I can do that and then mark them done.  If it needs to be done later, I don&#39;t want it to sit in the inbox.  I&#39;ll put it into a todo list app or my calendar instead and then archive it for reference if necessary.  
        &lt;/p&gt;
        &lt;a href=&#34;#fnref:2&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Setting Up Your Text Editor For JavaScript Development</title>
      <link>https://benmccormick.org/2014/10/12/200551.html</link>
      <pubDate>Sun, 12 Oct 2014 21:05:51 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2014/10/13/200551.html</guid>
      <description>&lt;p&gt;The coding workflow for JavaScript developers gets better all the time.  Over the last 10 years, the JavaScript ecosystem has built up a rich set of tools to make your life easier.  Most of the buzz around tooling comes from browser devtools and the various build systems available for JavaScript projects, but you can also take advantage of improved tools within your code editor.  While there are some great IDEs for JavaScript development out there like WebStorm and Visual Studio, most JavaScript developers seem to prefer lighter-weight text editors.  So this post is going to be a quick look at the tools I use for more seamless JavaScript development in a text editor.&lt;/p&gt;
&lt;h3 id=&#34;basics&#34;&gt;Basics&lt;/h3&gt;
&lt;p&gt;Before we get to anything JavaScript specific, there are a few important things to set up.  First, I&amp;rsquo;m assuming that you&amp;rsquo;re using a modern, extensible text editor. Those include, but are not limited to: &lt;a href=&#34;http://www.sublimetext.com/&#34;&gt;Sublime Text&lt;/a&gt;, &lt;a href=&#34;http://www.vim.org/&#34;&gt;Vim&lt;/a&gt;, &lt;a href=&#34;https://atom.io/&#34;&gt;Atom&lt;/a&gt; and &lt;a href=&#34;http://www.gnu.org/software/emacs/&#34;&gt;Emacs&lt;/a&gt;. There is great support for all of the below tips in each of these editors&lt;sup id=&#34;fnref:0&#34;&gt;&lt;a href=&#34;#fn:0&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;In addition you should have&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Reasonable default configurations&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;A fast system for navigating between files&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;Great code searching&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If you&amp;rsquo;re still working through those things, make sure to take the time to learn a bit more about your editor along with any JavaScript specific tools you use.  There&amp;rsquo;s a ton of efficiency you can gain from having those 3 things in place.&lt;/p&gt;
&lt;p&gt;Finally the first two tips below require &lt;a href=&#34;http://nodejs.org/&#34;&gt;node.JS&lt;/a&gt; and npm to be installed, as they rely on node libraries to function.  If you&amp;rsquo;ve never installed those before, the process is pretty painless.&lt;/p&gt;
&lt;p&gt;Once you have all of that in place, we can move on to other things.&lt;/p&gt;
&lt;h3 id=&#34;syntax-linting&#34;&gt;Syntax Linting&lt;/h3&gt;
&lt;p&gt;JavaScript is a dynamic, weakly-typed language.  It is also written by human beings.  As a result, it can be easy to start running bad code without realizing that it has problems.  Some types of problems you&amp;rsquo;ll find out about quickly.  Bad syntax will halt program execution for instance.  But others will linger, subtly effecting logic or just making the code hard to understand for future developers (including yourself).&lt;/p&gt;
&lt;p&gt;JavaScript linters (also called syntax checkers) can provide some of the safety of a compiler, and also help enforce a consistent set of styles to help maintain readability.  They are not magic.  JavaScript is still a weakly typed language with some weird syntactical sinkholes. It&amp;rsquo;s relatively easy to make logic mistakes if you&amp;rsquo;re undisciplined.  But linters are a great safety tool, especially for developers newer to JavaScript and its conventions.  Run as part of a build process, they can prevent you shipping bad code and help standardize conventions across a team&lt;/p&gt;
&lt;p&gt;While it&amp;rsquo;s a great idea to make linters part of your build process, you get even more power from integrating them with your editor.  Almost all modern text editors include some sort of plugin for displaying syntax errors and warnings in the gutter to the left of the text.  You can check out the integration pages for &lt;a href=&#34;http://eslint.org/docs/integrations/&#34;&gt;ESLint&lt;/a&gt; and &lt;a href=&#34;http://www.jshint.com/install/&#34;&gt;jsHint&lt;/a&gt; to get a feel for the plugins available for your editor.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;lintingpic.png&#34; alt=&#34;linting picture&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;ternjs--autocomplete&#34;&gt;TernJS + Autocomplete&lt;/h3&gt;
&lt;p&gt;Linters are great for telling you what not to do, but can&amp;rsquo;t give you much guidance on what you actually are able to do.  Fortunately we have other tools for that.  &lt;a href=&#34;http://ternjs.net/&#34;&gt;Tern.js&lt;/a&gt; is a fantastic library that provides &amp;ldquo;intellisense&amp;rdquo; style autocompleting for JavaScript code, along with other IDE-like features including documentation links and refactoring support. It&amp;rsquo;s not perfect, since JavaScript&amp;rsquo;s nondeterministic syntax sometimes makes it hard to tell what properties a variable will actually have at runtime, but it takes a good shot at it and is able to go pretty far, especially for libraries where it can expose the full API to you within the editor.  To get the most out of Tern, you&amp;rsquo;ll need to set up a Tern project definition, where you can specify any files that you always want loaded, and any plugins you want to use. The preloaded files is useful if you&amp;rsquo;re making global references to a namespace or library, and the plugins can give you support for module systems, so that you can handle references that are passed into a module from a different file in code using requireJS or Angular.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;ternjs.gif&#34; alt=&#34;ternjs picture&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;snippets&#34;&gt;Snippets&lt;/h3&gt;
&lt;p&gt;JavaScript development, especially on the front end, can involve a lot of repetitive boilerplate code&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34;&gt;5&lt;/a&gt;&lt;/sup&gt;.  Whether it&amp;rsquo;s module boilerplate like AMD require/define wrappers, library boilerplate like directive definitions in Angular or a Model definition in Backbone, or our own favorite patterns that we repeat a lot, we end up writing a lot of code over and over again.  Snippets are a great way to accomplish that.  They were one of the key features of Textmate when it first became popular.  Today they&amp;rsquo;re built in to Sublime Text and Atom, and there are popular libraries for both &lt;a href=&#34;https://github.com/SirVer/ultisnips&#34;&gt;Vim&lt;/a&gt; and &lt;a href=&#34;https://github.com/capitaomorte/yasnippet&#34;&gt;Emacs&lt;/a&gt; to simulate the same functionality.&lt;/p&gt;
&lt;p&gt;Snippets allow you to define templates for common boilerplate code, allowing you to quickly insert repetitive content, including adding hooks for text that will vary across uses.  For instance here&amp;rsquo;s a snippet I have defined for creating a new AMD module&lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34;&gt;6&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;#A new AMD define module
snippet dfn
define([$1],function($2) {
    $0  
});
endsnippet
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This allows me to type &lt;em&gt;dfn&amp;lt;tab&amp;gt;&lt;/em&gt; at any time to expand out the template.  Initially my cursor will be in spot &lt;code&gt;$1&lt;/code&gt;, and I can then enter text and tab to spot &lt;code&gt;$2&lt;/code&gt;, with my final tab ending me at &lt;code&gt;$0&lt;/code&gt;.  Snippet libraries can also provide other functionality like functions to show the current time, filename, or other contextual information.   Some can also mirror text so that you can enter a string once and have it appear throughout the template.  It can be a great time saver when you&amp;rsquo;re chugging through the boilerplate code of your project.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&#34;more-resources&#34;&gt;More Resources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;If you want to implement JavaScript syntax checking definitely check out &lt;a href=&#34;http://eslint.org/&#34;&gt;ESLint&lt;/a&gt; or &lt;a href=&#34;http://www.jshint.com/&#34;&gt;jsHint&lt;/a&gt;.  They both offer a lot more options and flexibility than &lt;a href=&#34;http://www.jslint.com/&#34;&gt;jsLint&lt;/a&gt;, the pioneer in this area.  It&amp;rsquo;s pretty easy to find an integration plugin for most common editors through those websites or Google, but &lt;a href=&#34;https://github.com/scrooloose/syntasticsu&#34;&gt;Syntastic&lt;/a&gt; for Vim and &lt;a href=&#34;https://github.com/SublimeLinter/SublimeLinter3j&#34;&gt;Sublime Linter&lt;/a&gt; for Sublime Text come especially recommended and have the advantage of supporting all 3 major JavaScript linters as well as syntax checking for multiple languages.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;http://ternjs.net/&#34;&gt;Tern&amp;rsquo;s website&lt;/a&gt; has great documentation and links to the editor specific implementations for different editors.  If you&amp;rsquo;re a Vim user I&amp;rsquo;d also recommend taking a look at &lt;a href=&#34;https://github.com/Valloric/YouCompleteMe&#34;&gt;YouCompleteMe&lt;/a&gt; for an improved autocomplete interface that works well with Tern and UltiSnips.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;For snippet libraries, you can take a look at &lt;a href=&#34;https://github.com/SirVer/ultisnips&#34;&gt;UltiSnips&lt;/a&gt; for Vim and &lt;a href=&#34;https://github.com/capitaomorte/yasnippet&#34;&gt;Yasnippet&lt;/a&gt; for Emacs.  If you want an application agnostic snippet solution, &lt;a href=&#34;http://kapeli.com/dash&#34;&gt;Dash&lt;/a&gt; is a documentation management program for OSX that also has a rich snippet component you can use in any program the same way you&amp;rsquo;d use an editor specific solution.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;footnotes&#34;&gt;
&lt;ol&gt;
    &lt;li class=&#34;footnote&#34; id=&#34;fn:0&#34;&gt;
        &lt;p&gt; Other than the lack of an official Tern plugin for Atom
        &lt;a href=&#34;#fnref:0&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li class=&#34;footnote&#34; id=&#34;fn:1&#34;&gt;
        &lt;p&gt;
        Sublime Text and Atom provide pretty reasonable defaults. Vim users could consider checking out my piece on &lt;a href=&#34;http://benmccormick.org/2014/07/14/learning-vim-in-2014-configuring-vim/&#34;&gt;configuring Vim&lt;/a&gt;.  I don&#39;t know enough to advise for Emacs, you&#39;re on your own their, but google is your friend.
        &lt;a href=&#34;#fnref:1&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li class=&#34;footnote&#34; id=&#34;fn:2&#34;&gt;
        &lt;p&gt;
        This really deserves a post of its own, not a footnote, but in general my approach to this is fuzzy search, split panes and a way to retrace my movements.   
        &lt;a href=&#34;#fnref:2&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li class=&#34;footnote&#34; id=&#34;fn:3&#34;&gt;
        &lt;p&gt;
        Sublime Text and Atom have reasonably nice built in search tools, but I&#39;d recommend using a plugin that integrates with ack or ag, two &lt;a href=&#34;http://benmccormick.org/2013/11/25/a-look-at-ack/&#34;&gt;very nice search tools&lt;/a&gt;.  I don&#39;t see such a plugin for Atom on their repository site right now, but the other 3 certainly support it.
        &lt;a href=&#34;#fnref:3&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li class=&#34;footnote&#34; id=&#34;fn:4&#34;&gt;
        &lt;p&gt;
        Hopefully not too much obviously
        &lt;a href=&#34;#fnref:4&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li class=&#34;footnote&#34; id=&#34;fn:5&#34;&gt;
        &lt;p&gt;
        This is using the syntax for Vim&#39;s Ultisnips plugin.
        &lt;a href=&#34;#fnref:5&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Custom Elements By Example</title>
      <link>https://benmccormick.org/2014/08/28/073300.html</link>
      <pubDate>Thu, 28 Aug 2014 08:33:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2014/08/28/073300.html</guid>
      <description>&lt;p&gt;The best attribute of HTML is its ability to be simultaneously machine-readable and human-readable.  I&amp;rsquo;d argue that it&amp;rsquo;s one of the biggest reasons for the web platform&amp;rsquo;s success. Anyone can  “view page source” and have some understanding of what they&amp;rsquo;re seeing.  Javascript based “Single Page Applications” have undermined this a bit.  Now the original HTML of a page may just be an empty body tag, and even when you inspect the generated page, it will probably just be a sea of div tags.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s going to start changing in the near future.  Custom Elements, part of the &lt;a href=&#34;http://www.w3.org/standards/techs/components#w3c_all&#34;&gt;Web Components spec&lt;/a&gt;, are a way of bringing back the semantic web.  They allow you to encapsulate HTML and Javascript functionality into &amp;ldquo;elements&amp;rdquo; which you can include in your HTML like any existing native element, with all their semantic benefits.   The best part? They&amp;rsquo;re &lt;a href=&#34;http://developer.telerik.com/featured/web-components-ready-production/&#34;&gt;usable in production now&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;so-what-does-it-look-like-to-use-custom-elements&#34;&gt;So What does it look like to use custom elements?&lt;/h3&gt;
&lt;p&gt;Talking about this stuff is great, but this is an API for shippable code, not just an abstract spec. So let&amp;rsquo;s look at a simple example.  In a past job, I made pretty extensive use of the &lt;a href=&#34;http://jqueryui.com/&#34;&gt;jQuery UI&lt;/a&gt; widget library.  jQuery UI is great, but I always found it a bit akward to work with in practice. When it&amp;rsquo;s used, it takes an existing HTML Element, usually a &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; and transforms it into a widget.  That means that to understand the end result created by the widget code, you have to look in at least 2 places, the original HTML code that contained the transformed element, and the JavaScript code that contained the call. It creates mental overhead knowing that you always had to remember to widgetize the dom element when it&amp;rsquo;s rendered. It also means accepting that the final result of the widget might look significantly different than the original.  For instance, here&amp;rsquo;s the before or after for the progress bar widget.  I chose it for it&amp;rsquo;s simplicity, but you can see that the final result is barely recognizable from the source.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;code_comparison-1.png&#34; alt=&#34;source -&gt; display&#34;&gt;&lt;/p&gt;
&lt;p&gt;This seems like the perfect opportunity to use a custom element.  If we can encapsulate all that behavior, we&amp;rsquo;ll be able to ensure that the progress bar is always rendered when it appears, and we can hide any ugly transformed DOM elements underneath a shiny semantic element.  Sounds great! So let&amp;rsquo;s see how this works.&lt;/p&gt;
&lt;p&gt;To start, we need an object to serve as our progress bar element&amp;rsquo;s prototype.  It should inherit from the base &lt;em&gt;HTMLElement&lt;/em&gt; class. We can create the prototype object like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; ProgressBar  &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;Object&lt;/span&gt;.create(HTMLElement.prototype);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now that we have our Prototype element, we can register it as a custom element using the &lt;code&gt;document.registerElement&lt;/code&gt; API. For now this is only natively available in Chrome, but it&amp;rsquo;s quite reasonable to &lt;a href=&#34;https://github.com/WebReflection/document-register-element&#34;&gt;polyfill&lt;/a&gt;. &lt;code&gt;registerElement&lt;/code&gt; accepts 2 arguments: the name of the element&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;, and an optional second argument to allow you to specify a prototype for your element.  So let&amp;rsquo;s set up a &lt;code&gt;progress-bar&lt;/code&gt; element:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;document&lt;/span&gt;.registerElement(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;progress-bar&amp;#39;&lt;/span&gt;,{
  prototype&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;ProgressBar
});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Our &lt;code&gt;ProgressBar&lt;/code&gt; object will now serve as the prototype for the &lt;code&gt;progress-bar&lt;/code&gt; element.  That means we can extend it and give it extra functionality which will then be available on every instance of that element.  Besides allowing us to attach arbitrary properties or functionality to an element, this lets us hook into the &amp;ldquo;lifecycle callbacks&amp;rdquo; of HTML Elements, which you can see in this chart from &lt;a href=&#34;https://github.com/WebReflection/document-register-element&#34;&gt;HTML5Rocks&lt;/a&gt;:&lt;/p&gt;
&lt;table class=&#34;table&#34;&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Callback name&lt;/th&gt;
      &lt;th&gt;Called when&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;createdCallback&lt;/td&gt;
      &lt;td&gt;an instance of the element is created&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;attachedCallback&lt;/td&gt;
      &lt;td&gt;an instance was inserted into the document&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;detachedCallback&lt;/td&gt;
      &lt;td&gt;an instance was removed from the document&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;attributeChangedCallback(attrName, oldVal, newVal)&lt;/td&gt;
      &lt;td&gt;an attribute was added, removed, or updated&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Let&amp;rsquo;s start by looking at createdCallback.  Since this gets run when the element is first created, this is a great time to run any initialization code that doesn&amp;rsquo;t require the element to be present in the DOM yet.  Since jQuery UI&amp;rsquo;s progress bar code doesn&amp;rsquo;t require the element to be attached to the DOM, we can do all of our initialization here.  That could look something like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;ProgressBar.createdCallback &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;() {
  &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; bar &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; $(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;&amp;lt;div id=&amp;#34;bar&amp;#34;&amp;gt;&amp;#39;&lt;/span&gt;).progressbar({
    value&lt;span style=&#34;color:#ff79c6&#34;&gt;:+&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.getAttribute(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;value&amp;#39;&lt;/span&gt;) &lt;span style=&#34;color:#ff79c6&#34;&gt;||&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;0&lt;/span&gt;
  });
  $(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;).html(bar);
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So using jQuery, we create a new div element and immediately transform it into a progressbar object. Then we attach it inside our custom element container. Pretty straightforward.&lt;/p&gt;
&lt;p&gt;Note that we set the value of our progress bar from the &lt;em&gt;value&lt;/em&gt; attribute of our element.  HTML attributes provide a very convenient &amp;ldquo;public API&amp;rdquo; for Custom Elements.  You have complete access to an elements attributes inside these callbacks, allowing for easy declarative APIs. In the case of our simple progress bar, &lt;code&gt;value&lt;/code&gt; is the only attribute we care about, and other attributes are ignored.&lt;/p&gt;
&lt;p&gt;But what if the value of our element changes?  Attributes aren&amp;rsquo;t a one time only API.  If we want to react to changes in the attribute, we can use the aptly named &lt;em&gt;attributeChangedCallback.&lt;/em&gt;  That callback fires everytime an attribute changes, allowing us to catch the change and respond appropriately.  A more sophisticated element might contain a registry of callbacks for different elements, but for this example we can focus on changes to value.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;ProgressBar.attributeChangedCallback &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(attrName, oldVal, newVal) {
  &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; $bar;
  &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt;(attrName &lt;span style=&#34;color:#ff79c6&#34;&gt;===&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;value&amp;#39;&lt;/span&gt;) {
    $bar &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; $(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.getElementById(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;))
    $bar.progressbar(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;value&amp;#39;&lt;/span&gt;,&lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt;newVal);
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And that&amp;rsquo;s it! We now have a working &lt;code&gt;progress-bar&lt;/code&gt; element, that we can put anywhere in our HTML with no extra js configuration.&lt;/p&gt;
&lt;p data-height=&#34;257&#34; data-theme-id=&#34;8140&#34; data-slug-hash=&#34;cFyep&#34; data-default-tab=&#34;result&#34; class=&#39;codepen&#39;&gt;See the Pen &lt;a href=&#39;http://codepen.io/ben336/pen/cFyep/&#39;&gt;Custom Elements Progressbar Example&lt;/a&gt; by Ben McCormick (&lt;a href=&#39;http://codepen.io/ben336&#39;&gt;@_benmccormick&lt;/a&gt;) on &lt;a href=&#39;http://codepen.io&#39;&gt;CodePen&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Of course there is plenty more we could do.  A more complicated element might require some initialization to be moved to the &lt;code&gt;attachedCallback&lt;/code&gt;, and might require better cleanup using the &lt;code&gt;detachedCallback&lt;/code&gt;.  For communication with the rest of our app that didn&amp;rsquo;t fit well into the &amp;ldquo;changing attributes&amp;rdquo; model, we might need to implement an eventing system or global registry for accessing data.  But those are all additions on this basic, useful building block.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re interested in trying out custom elements, there&amp;rsquo;s never been a better time to get started. It&amp;rsquo;s easy to try out proof of concepts in Chrome, and there&amp;rsquo;s a &lt;a href=&#34;https://github.com/WebReflection/document-register-element&#34;&gt;light-weight polyfill&lt;/a&gt; with support back to IE9 for those who want to start using them in production.  If this is something that excites you, there&amp;rsquo;s no reason not to start using this tool in your code today.&lt;/p&gt;
&lt;h3 id=&#34;more-resources&#34;&gt;More Resources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;HTML5Rocks has an awesome &lt;a href=&#34;https://github.com/WebReflection/document-register-element&#34;&gt;detailed look&lt;/a&gt; at Custom Elements that covers all of the ground we looked at here, and more.  If you want to dive deeply into this feature, it&amp;rsquo;s a great read to get started.&lt;/li&gt;
&lt;li&gt;Telerik posted another &lt;a href=&#34;http://developer.telerik.com/featured/web-components-ready-production/&#34;&gt;great piece&lt;/a&gt; on this topic a few weeks ago, which focuses more on the case for Custom Elements being production ready now&lt;/li&gt;
&lt;li&gt;If you&amp;rsquo;re interested in using more than just Custom Elements, &lt;a href=&#34;http://www.polymer-project.org/&#34;&gt;The Polymer Project&lt;/a&gt; by Google is an ambitious library built around the Web Component spec.  They attempt to polyfill the whole spec, then wrap convenience functions around the low level elements.  It&amp;rsquo;s an interesting, ambitious project, though not yet ready for production.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;footnotes&#34;&gt;
&lt;ol&gt;
    &lt;li class=&#34;footnote&#34; id=&#34;fn:1&#34;&gt;
        &lt;p&gt;
        The Web Components spec specifies that valid names should be in the form of 2 words separated by a hyphen in order to avoid conflicts with existing and future &#34;official&#34; HTML elements.
        &lt;a href=&#34;#fnref:1&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>The Debugging Toolbox</title>
      <link>https://benmccormick.org/2014/08/19/063500.html</link>
      <pubDate>Tue, 19 Aug 2014 07:35:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2014/08/19/063500.html</guid>
      <description>&lt;p&gt;Do you know a &lt;em&gt;Problem Solver&lt;/em&gt;?  They&amp;rsquo;re the ones who can take a crazy, vague bug report from a client and come up with a fix in an hour.  The ones who everybody else asks for help when the project deadline is creeping up.  The ones who get shipped out to the client site when the field team is out of their depth.  In school they were the person you called at 1AM the night before your project was due, hoping for a miracle.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m guessing you can think of somebody.  Problem solving is a valuable gift, something that stands out.  But the truth is, all software developers should be problem solvers.  It&amp;rsquo;s a key part of our jobs.  We just happen to call it debugging.&lt;/p&gt;
&lt;p&gt;Debugging is hard.  As developers, we&amp;rsquo;re faced with vague problem descriptions, massive code bases, and constant pressure to move our projects forward.  But you can do some great things if you&amp;rsquo;re disciplined about getting better at debugging.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve built up my own debugging process over the years.  It&amp;rsquo;s nothing more exciting than &lt;em&gt;Problem Solving 101&lt;/em&gt;, but it&amp;rsquo;s a productive way of working that lets me get stuff fixed quickly and keep issues from happening again. It helps me fix things even when I&amp;rsquo;m not qualified to do so, and keeps maintenance work from overwhelming my ability to get things done.  If that sounds useful to you, you should probably keep reading. Here&amp;rsquo;s my process.&lt;/p&gt;
&lt;h3 id=&#34;step-1-define-the-problem&#34;&gt;Step 1: Define The Problem&lt;/h3&gt;
&lt;p&gt;The need to define the problem seems like common sense, but it often gets skipped.  The first thing you need before fixing a problem is a clear definition of what the problem looks like.  That means a detailed look at 2 things:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;What is the current behavior?&lt;/li&gt;
&lt;li&gt;What should the behavior be?&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The second question often gets neglected.  At Windsor Circle, we have a system that receives product records from another system.  The data it was receiving occasionally contained blank product titles, which was not considered valid data.  I was asked to ensure that the second system would not pass invalid data.  I could of course have just decided to not pass any records that had blank product data.  Or I could have filled them with a &lt;code&gt;&amp;quot;None&amp;quot;&lt;/code&gt; string, calculated a value from other attributes, or a thousand other approaches.  Since each of these would have removed the current bad behavior, I might have been able to slip them by for a while.  Instead I asked what the correct behavior should be, which led to a longer discussion and an eventual decision that we would need to handle a small set of empty titles after all.  At that point I was able to actually deal with the problem.&lt;/p&gt;
&lt;h3 id=&#34;step-2-reproduce-the-problem&#34;&gt;Step 2: Reproduce The Problem&lt;/h3&gt;
&lt;p&gt;After you define the problem, the next step is to reproduce it.  &lt;strong&gt;Do not skip this step.&lt;/strong&gt;  If you can&amp;rsquo;t define and consistently reproduce a situation where the problem occurs, it will be impossible to know whether you&amp;rsquo;ve solved it.  If the issue involves a lot of specific circumstances and moving parts, or only occurs sporadically, this may be the hardest part of the whole process.  The things you want to keep in mind:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;What are the circumstances under which this occurs? Always? Only on certain browsers/OSs/hardware?  Is it a timing issue? A timezone issue? All of the above?&lt;/li&gt;
&lt;li&gt;Is there a series of actions that I can do that makes this occur every single time?&lt;/li&gt;
&lt;li&gt;Am I confident that I know all of the situations that cause this to occur?&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Answering #1 is the first step.  If you can say yes to #2 you&amp;rsquo;re in a fantastic position to proceed.  If you can say yes to #3, you need to get a lot more suspicious and cynical.  But the more confident you can be about each of these, the better equipped you&amp;rsquo;ll be going forward.&lt;/p&gt;
&lt;h3 id=&#34;step-3-narrow-the-scope&#34;&gt;Step 3: Narrow the Scope&lt;/h3&gt;
&lt;p&gt;Now that we&amp;rsquo;ve established our problem and hopefully found a consistent path to reproduce it, we&amp;rsquo;re ready to start rooting out our problem.&lt;/p&gt;
&lt;p&gt;The first step is to narrow the scope.  In a normal software environment, you&amp;rsquo;re likely to be dealing with a large amount of your own code, as well as 3rd party libraries and APIs, some sort of environment, and unpredictable user behavior.  That&amp;rsquo;s a lot of uncertainty and information to process.  I&amp;rsquo;ve seen developers who really try to understand the whole system before even thinking about the problem.  But in many cases that&amp;rsquo;s unrealistic.  Instead, you should be trying to get rid of as much of that information as possible by narrowing the scope of where the bug might exist.  There are 4 main ways of narrowing scope.&lt;/p&gt;
&lt;h4 id=&#34;prove-that-the-problem-is-unique-to-a-component&#34;&gt;Prove That The Problem Is Unique To A Component&lt;/h4&gt;
&lt;p&gt;If you want to eliminate a system component from consideration, one good way is by proving that the issue is not unique to it.  This works particularly well for platform issues.  For instance, you might prove that something is not a browser-specific problem by showing that the issue occurs in all browsers.  This can give you some firm ground to stand on.  If you do expose a platform-specific issue, that can be good news too, as they tend to be better documented.&lt;/p&gt;
&lt;h4 id=&#34;follow-the-flow&#34;&gt;Follow The Flow&lt;/h4&gt;
&lt;p&gt;If your problem is a data issue (and many issues are), you can also narrow the scope by following the flow of data through your application.  There are 2 main ways to do this.  One is by starting at the beginning of the flow, where the data initially comes into the system, and follow it through, looking to see where things go wrong. You could also start at the end with the incorrect output and try to trace back and see where it came from.&lt;/p&gt;
&lt;p&gt;A good debugging tool is a great asset here.  There may be times when you&amp;rsquo;re forced to work without one though (for example, working in an environment you don&amp;rsquo;t control or a domain-specific language without adequate tooling).  In that case you can get by with log statements, or even changing the code to output a result early.  Regardless, what you want is clear evidence that data was good at a certain point, or already bad at another.  This allows you to eliminate that code from consideration and focus in on the code before it.&lt;/p&gt;
&lt;h4 id=&#34;follow-the-history&#34;&gt;Follow The History&lt;/h4&gt;
&lt;p&gt;If you know this problem was introduced relatively recently, you can approach it by figuring out what changed.  Version control systems in particular provide great tools for this type of analysis.  If you know that the change was introduced within a set period of time, that provides an additional dimension from which you can narrow the scope and filter ideas.&lt;/p&gt;
&lt;h3 id=&#34;step-4-make-an-educated-guess&#34;&gt;Step 4: Make An Educated Guess&lt;/h3&gt;
&lt;p&gt;Now it&amp;rsquo;s time to make a guess at where the problem may be.  It&amp;rsquo;s important for this to be an &lt;strong&gt;educated&lt;/strong&gt; guess.  You don&amp;rsquo;t want to check code at random.  Your starting point should come from your past experience with similar issues, or be the result of research into the problem. I can&amp;rsquo;t overstate how important research can be. It&amp;rsquo;s always worth starting with a quick Google search, since it might save you hours of time looking on your own.  Once you&amp;rsquo;ve narrowed the scope a bit, you can revisit your research, looking specifically for known issues with a specific component for instance.  Your guesses also can be a follow-up to new information from Step #5.  Despite the ordering I give here, debugging is never a completely linear process. You need to have all of these tools in your toolbox.  Experience will help you know which to use.&lt;/p&gt;
&lt;h3 id=&#34;step-5-understand-the-behavior&#34;&gt;Step 5: Understand The Behavior&lt;/h3&gt;
&lt;p&gt;If you&amp;rsquo;ve managed to isolate the unwanted behavior a bit and have a guess where the problem might be, now&amp;rsquo;s the time to read more deeply into the code.  What is actually happening in there?  Does the logic of the code match your understanding of its purpose?  Do you see any red flags or danger signs?&lt;/p&gt;
&lt;p&gt;I once interviewed a candidate for a programming job who told me he didn&amp;rsquo;t read code very much while debugging.  Instead he made changes to observe the new behavior and kept fiddling until the output worked the way he wanted.  While that might work for aligning text on a Wordpress site, you simply can&amp;rsquo;t get away with that in a complex application.  Reading and understanding code quickly is a skill, but it&amp;rsquo;s one you must develop if you want to be a productive developer.&lt;/p&gt;
&lt;h3 id=&#34;step-6-repeat-steps-3-5-until-you-have-a-thesis&#34;&gt;Step 6: Repeat Steps 3-5 until you have a thesis&lt;/h3&gt;
&lt;p&gt;If you&amp;rsquo;ve narrowed your scope and read some code, you might have an idea about what you think the problem is and how to solve it.  If you do, then proceed to step #6.  If not, take what you&amp;rsquo;ve learned and use it to loop back to step #3, to reduce the scope even more.&lt;/p&gt;
&lt;h3 id=&#34;step-7-test-your-thesis&#34;&gt;Step 7: Test your Thesis&lt;/h3&gt;
&lt;p&gt;If you think you have a handle on the problem, now&amp;rsquo;s the time to test it.  There are a few ways to do that.  One obvious way is to apply a fix and see if the problem goes away.  But if the fix would be expensive in time, money or complexity or if you&amp;rsquo;re afraid of treating the symptoms rather than the disease, you can also look into creating a simpler test case.&lt;/p&gt;
&lt;p&gt;Earlier this month I encountered an issue where a &lt;a href=&#34;http://handlebarsjs.com/&#34;&gt;handlebars&lt;/a&gt; template was failing to render correctly occasionally.  After digging in and narrowing the scope, I determined that the issue occurred only on Chrome, and seemed to happen randomly after a few renders.  I was able to create a &lt;a href=&#34;http://jsfiddle.net/w2gtm3yx/1/&#34;&gt;very simple test case&lt;/a&gt; that reproduced the problem in a jsFiddle. I didn&amp;rsquo;t use any of my own data. Instead I just created the simplest test that I expected to fail.  And it did.  That gave me confidence that the issue was in the Handlebars-Chrome interaction, and I was able to find a workaround by looking through their &lt;a href=&#34;https://github.com/wycats/handlebars.js/issues/832&#34;&gt;issues page&lt;/a&gt; on Github&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.  That type of iteration on your test cases also provides useful reference material in case the issue reoccurs.&lt;/p&gt;
&lt;h3 id=&#34;step-8-repeat-3-7-until-you-can-no-longer-reproduce&#34;&gt;Step 8: Repeat 3-7 until you can no longer reproduce&lt;/h3&gt;
&lt;p&gt;If your thesis turns out to be wrong, take your new knowledge and go back to step #3. It&amp;rsquo;s important to understand that this isn&amp;rsquo;t a rigidly structured process though.  This also may be time to go back and double check steps 1 &amp;amp; 2.  Do you really know what the right behavior is?  Have you learned anything that might change that?  If you couldn&amp;rsquo;t reproduce the issue after a change, are you sure that you&amp;rsquo;ve really fixed it?  Or were there holes in your original path to reproduce it?  A healthy amount of paranoia helps here.&lt;/p&gt;
&lt;h3 id=&#34;step-9-document-and-future-proof&#34;&gt;Step 9: Document and future-proof&lt;/h3&gt;
&lt;p&gt;Once you&amp;rsquo;ve fixed the problem, or gotten to a point where you&amp;rsquo;re not going to continue for some reason, there&amp;rsquo;s one very important last step.  Document what you&amp;rsquo;ve learned.  If you made a change to the code that &amp;ldquo;looks wrong&amp;rdquo; but fixes the problem, leave a comment explaining it, and save it from future &amp;ldquo;code cleanups&amp;rdquo;.  If you can&amp;rsquo;t reproduce the problem consistently and it still exists, document what you learned in a bug tracker so that somebody can come back to it later.  If you isolated the problem to a 3rd party component, file a bug report and include your test case (simplified as much as possible).  If you created a useful test case, automate it or add it as a reference somewhere.  Exact processes will vary by team, but the key phrase here is &amp;ldquo;Those who don&amp;rsquo;t learn from the past are doomed to repeat it.&amp;rdquo;  Are you going to bruise this bug or bury it?  Make sure you can fix the problem quickly if it happens again. If you can do anything to keep it from coming back, do it.&lt;/p&gt;
&lt;h3 id=&#34;the-takeaway&#34;&gt;The Takeaway&lt;/h3&gt;
&lt;p&gt;Real world engineering means dealing with code you don&amp;rsquo;t understand.  That might be your coworkers&#39; code, a 3rd party library, a buggy video driver, or your own 3 year old code. To do that effectively you need a process.  That might be mine, or one of your own, it could be formal, or just built on habit.  But make sure you have one.  The ability to dive in quickly, understand what&amp;rsquo;s going on and create a fix will set you apart.  It&amp;rsquo;s not that hard, but it takes discipline, creativity, and most of all practice.  So go ahead and start fixing something.  Maybe you&amp;rsquo;ll be the &lt;em&gt;Problem Solver&lt;/em&gt; next time&lt;/p&gt;
&lt;div class=&#34;footnotes&#34;&gt;
&lt;ol&gt;
    &lt;li class=&#34;footnote&#34; id=&#34;fn:1&#34;&gt;
        &lt;p&gt;
        Chrome 36.0.1985.143 seems to have resolved the issue.
        &lt;a href=&#34;#fnref:1&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Component Based Development</title>
      <link>https://benmccormick.org/2014/08/07/063000.html</link>
      <pubDate>Thu, 07 Aug 2014 07:30:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2014/08/07/063000.html</guid>
      <description>&lt;p&gt;If you look back at the history of JavaScript and the client-side web as a development platform, you can see that there were several critical turning points for the language. Javascript has evolved from a &lt;a href=&#34;http://www.computer.org/csdl/mags/co/2012/02/mco2012020007.html&#34;&gt;10-day toy language&lt;/a&gt; to possibly the &lt;a href=&#34;http://adambard.com/blog/top-github-languages-for-2013-so-far/&#34;&gt;most used language in the world&lt;/a&gt;, but that didn&amp;rsquo;t happen overnight.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;timeline.png&#34; alt=&#34;JavaScript timeline&#34;&gt;&lt;/p&gt;
&lt;p&gt;JavaScript&amp;rsquo;s growth started with its adoption as the lingua franca of the web when it shipped with Netscape and Internet Explorer in the 90s.  The introduction of Ajax and asynchronous data exchange in the mid-aughts was another sea change, bringing the potential for truly responsive web applications like Gmail for the first time.  &lt;a href=&#34;http://jquery.com/&#34;&gt;jQuery&lt;/a&gt;&amp;rsquo;s introduction in 2006 dramatically reduced the pain involved in cross-browser development for rich applications. And the last 5 years have brought 2 more major changes with &lt;a href=&#34;http://nodejs.org/&#34;&gt;Node.JS&lt;/a&gt; and a &lt;a href=&#34;http://blog.stevensanderson.com/2012/08/01/rich-javascript-applications-the-seven-frameworks-throne-of-js-2012/&#34;&gt;raft of MVC frameworks&lt;/a&gt;.  NodeJS is a server-side technology, but it has spurred a huge standardization and improvement in tooling for the web platform. That, along with great work by browser vendors on their developer tools, has led to drastically easier workflows for front end developers.  At the same time, frameworks like BackboneJS, AngularJS and EmberJS have brought architecture concepts to the client-side and made a new type of &amp;ldquo;Single Page App&amp;rdquo; possible and easy to build.&lt;/p&gt;
&lt;p&gt;Those 5 shifts, along with other significant events like Google&amp;rsquo;s creation of Chrome and the rise of mobile, have shaped the web development world as we see it today. Depending on who you listen to though, we may be on the cusp of another pivotal moment.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Component Based Development&lt;/em&gt; is a blanket term I&amp;rsquo;m using to describe a movement that has been growing over the past year in web development.  The results of this movement have taken several forms.  There&amp;rsquo;s an &lt;a href=&#34;http://www.w3.org/standards/techs/components#w3c_all&#34;&gt;official W3C standard&lt;/a&gt;, Web Components, that will eventually be available in all browsers natively.  That standard has polyfills, which allow developers to begin using Web Components now, along with convenience extensions.  Several existing MVC frameworks have provided component features inspired by the Web Component spec.  And there are alternative component implementations, which embrace the ideas behind component based development without embracing the specific implementation of Web Components.&lt;/p&gt;
&lt;h3 id=&#34;so-what-is-component-based-development&#34;&gt;So what is Component Based Development?&lt;/h3&gt;
&lt;p&gt;The heart of the component based development movement is a desire to provide greater code reusability and abstraction by bundling functionality into small composable components.  JavaScript applications started as monoliths.  The language doesn&amp;rsquo;t provide private attributes by default, and applications were initially mostly small, so everything lived in the global scope.  As applications have become more complex, this has changed, first with namespacing, then with the module pattern, and again with module loaders like requireJS and Browserify.  The features mapped out by the Web Components standard will build on this trend.  Component based development in general is the natural conclusion of the march to modularity.  Components are intended to be &amp;ldquo;black box&amp;rdquo; building materials.  They have an API, but the developer doesn&amp;rsquo;t need to know about the internals, and ideally can&amp;rsquo;t take advantage of that knowledge regardless.&lt;/p&gt;
&lt;p&gt;Talking about this type of abstraction is nothing new.  Whether you&amp;rsquo;re using the module pattern or Backbone Views, it&amp;rsquo;s always been a best practice to keep internal implementations hidden.  But web components in particular give this more teeth, by discouraging external CSS and Javascript from accessing the internal dom tree of the element. Other implementations can&amp;rsquo;t rely on that native split yet, but they similarly promote a declarative style that discourages tightly coupled micro-managing code.&lt;/p&gt;
&lt;p&gt;Components also have the potential to provide greater readability.  Compare Google Map&amp;rsquo;s current &lt;em&gt;Hello World&lt;/em&gt; example, with a web component powered alternative:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;meta name=&amp;quot;viewport&amp;quot; content=&amp;quot;initial-scale=1.0, user-scalable=no&amp;quot; /&amp;gt;
    &amp;lt;style type=&amp;quot;text/css&amp;quot;&amp;gt;
      html { height: 100% }
      body { height: 100%; margin: 0; padding: 0 }
      #map-canvas { height: 100% }
    &amp;lt;/style&amp;gt;
    &amp;lt;script type=&amp;quot;text/javascript&amp;quot;
      src=&amp;quot;https://maps.googleapis.com/maps/api/js?key=API_KEY&amp;quot;&amp;gt;
    &amp;lt;/script&amp;gt;
    &amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;
      function initialize() {
        var mapOptions = {
          center: new google.maps.LatLng(-34.397, 150.644),
          zoom: 8
        };
        var map = new google.maps.Map(document.getElementById(&amp;quot;map-canvas&amp;quot;),
            mapOptions);
      }
      google.maps.event.addDomListener(window, &#39;load&#39;, initialize);
    &amp;lt;/script&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;div id=&amp;quot;map-canvas&amp;quot;/&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;meta name=&amp;quot;viewport&amp;quot; content=&amp;quot;initial-scale=1.0, user-scalable=no&amp;quot; /&amp;gt;
    &amp;lt;link rel=&amp;quot;import&amp;quot; href=&amp;quot;google-maps.html&amp;quot;&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;google-map&amp;gt;&amp;lt;/google-map&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Quite a readability difference right?  Of course all of that Javascript and CSS didn&amp;rsquo;t simply vanish.  It still needs to exist somewhere, in this case within an imported HTML file.  But it can be encapsulated and looked at only when necessary.  The user who&amp;rsquo;s just glancing at your template can get a big picture view when she needs it, and then know where to dive in when she&amp;rsquo;s specifically interested in your mapping technology.&lt;/p&gt;
&lt;p&gt;In the end this is just another way of managing complexity.  There is unavoidable complexity associated with connecting to the Google Maps API and styling the map appropriately.  But when that complexity sits inside an element, it reduces the cognitive load of looking at HTML. That allows you to focus on the semantic meanings of element and the document structure. This kind of clarity is much nicer than our current status quo of searching  through a Javascript modified &amp;ldquo;div soup&amp;rdquo; to figure out how our generated DOM is structured.  With current MVC frameworks the HTML may tell you nothing about the final DOM without going through several Javascript files.  The transparency of components is a reclamation of one of the Web&amp;rsquo;s original central advantages: a semantic markup language that was both human and machine readable.  The tension between the needs of web &amp;ldquo;documents&amp;rdquo; and &amp;ldquo;applications&amp;rdquo; has slowly eroded the Web&amp;rsquo;s declarative foundations, but component implementations do their best to embrace it.&lt;/p&gt;
&lt;h3 id=&#34;so-why-should-i-care&#34;&gt;So Why Should I Care?&lt;/h3&gt;
&lt;p&gt;Did that introduction excite you?  Or are you sitting there yawning?  You may think this is solving problems you don&amp;rsquo;t have. You also might be the guy still supporting IE8, who can&amp;rsquo;t even contemplate worrying about &amp;ldquo;Web Standards&amp;rdquo; if they aren&amp;rsquo;t even supported in IE11.  If that&amp;rsquo;s you, it&amp;rsquo;s still worth following this movement, even if you&amp;rsquo;re not coding like this just yet on your current projects.&lt;/p&gt;
&lt;p&gt;For one thing, the component based mentality is already having a big effect on the crop of frameworks that people are using &lt;strong&gt;now&lt;/strong&gt;.  EmberJS and Angular have supported component-like features for a while now.  KnockoutJS (which supports back to IE6!) is about to release significant support for a component-based development strategy. And the latest JavaScript Framework darling, Facebook&amp;rsquo;s ReactJS, is a completely component based library that supports browsers back to IE8.&lt;/p&gt;
&lt;p&gt;Component based development has also gained significant support in the community.  I already mentioned the strong support from existing libraries, but there&amp;rsquo;s more to it than that. &lt;a href=&#34;http://facebook.github.io/react/&#34;&gt;Facebook&lt;/a&gt;, &lt;a href=&#34;http://www.polymer-project.org/&#34;&gt;Google&lt;/a&gt;, and &lt;a href=&#34;http://mozbrick.github.io/&#34;&gt;Mozilla&lt;/a&gt;, three of the web&amp;rsquo;s foundational companies, have all released component based libraries.  Google&amp;rsquo;s Polymer library in particular has been featured as the center of their web developer tooling lately.  Web Components are already supported in Chrome and Firefox.  Along with the community support and the trend towards auto-updating browsers, this is likely to be a relevant every-day technology sooner than you may think.&lt;/p&gt;
&lt;h3 id=&#34;the-takeaway&#34;&gt;The Takeaway&lt;/h3&gt;
&lt;p&gt;2014 is an interesting time for web development.  There&amp;rsquo;s a lot to be excited about, as the component paradigm is leading to a lot of interesting experiments that create new possibilities.  Ideas like React&amp;rsquo;s Virtual DOM and Polymer&amp;rsquo;s completely declarative application structures are going to be tested and tried, and we&amp;rsquo;re likely to be better off in the end.&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s also plenty to be skeptical about.  The lack of any known support for Web Components in Safari or IE is troubling.  While Polymer&amp;rsquo;s &amp;ldquo;everything is an element&amp;rdquo; philosophy is fascinating, I suspect that we&amp;rsquo;ll look back and see it as an example of taking a good idea too far.  And like any technology, until it&amp;rsquo;s been proven in production, we can&amp;rsquo;t really know how these technologies will evolve.&lt;/p&gt;
&lt;p&gt;For anyone invested in the Web Platform, it&amp;rsquo;s time to be informed. Regardless of where each individual spec goes, the ideas behind this movement are going to influence our professions for years to come.  Over the next month or so, I&amp;rsquo;m going to be diving deep into the current state of components, taking a look at the various aspects of the Web Component spec and also looking at the various libraries that are providing their own take on component based development. I hope you&amp;rsquo;ll come along, and help grow the conversation about the future of the web platform.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&#34;more-resources&#34;&gt;More Resources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;In &lt;a href=&#34;http://addyosmani.com/blog/the-webs-declarative-composable-future/&#34;&gt;The Web&amp;rsquo;s Declarative, Composable Future&lt;/a&gt; Addy Osmani lays out a manifesto for component based development, and Web Components in particular.  If you&amp;rsquo;re struggling to understand why somebody would want Web Components, this is the piece to read.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;TJ VanToll reminds us that &lt;a href=&#34;http://developer.telerik.com/featured/web-components-arent-ready-production-yet/&#34;&gt;Web Components Aren&amp;rsquo;t Ready For Production&amp;hellip; Yet&lt;/a&gt; on Telerik&amp;rsquo;s Developer Blog.  He does a good job of higlighting the browser support issues along with the difficulties of polyfilling this particular technology.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;This &lt;a href=&#34;https://github.com/knockout/knockout/issues/1273&#34;&gt;Github discussion&lt;/a&gt; is an interesting look into the thought process of why a traditional MVC library would be interested in providing component features, and the value they bring.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Learning Vim in 2014: Search</title>
      <link>https://benmccormick.org/2014/08/03/201620.html</link>
      <pubDate>Sun, 03 Aug 2014 21:16:20 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2014/08/04/201620.html</guid>
      <description>&lt;p&gt;Have you ever tried to summarize something that was just too big to explain?  I&amp;rsquo;ve covered a lot of ground in my posts on Vim this past month, but it&amp;rsquo;s only scratched the surface of what Vim has to offer.  The goal was to create a foundation that people could start with, and then let them build on their own. There&amp;rsquo;s not a conclusive way to say what somebody &amp;ldquo;needs to know&amp;rdquo; when learning Vim.  Most people don&amp;rsquo;t (and shouldn&amp;rsquo;t) use every feature of the editor, they use the ones that make sense for them.  So I&amp;rsquo;ve tried to cover the things that I know people have found useful, and the philosophy behind how Vim works, and then let you figure out what you&amp;rsquo;d like to use on your own.  This post wraps up the series, but I wanted to highlight one last feature of Vim, its fantastic search capabilities.&lt;/p&gt;
&lt;h3 id=&#34;search&#34;&gt;Search&lt;/h3&gt;
&lt;p&gt;Vim has an extremely powerful built in search tool.  To use it, you can type &lt;code&gt;/&lt;/code&gt; at anytime in normal mode to start entering search terms.  For instance &lt;code&gt;/foo&lt;/code&gt; followed by enter searches for the next occurrence of &lt;code&gt;foo&lt;/code&gt; in the document.  You can then skip over matches with &lt;code&gt;n&lt;/code&gt; or go backwards with &lt;code&gt;N&lt;/code&gt;.  If you wanted to start by searching backwards, you could have started with &lt;code&gt;?foo&lt;/code&gt; instead of &lt;code&gt;/foo&lt;/code&gt;, in which case &lt;code&gt;n&lt;/code&gt; and &lt;code&gt;N&lt;/code&gt; would reverse behavior, with &lt;code&gt;N&lt;/code&gt; moving forward in the document and &lt;code&gt;n&lt;/code&gt; moving back.  It&amp;rsquo;s easiest to think of &lt;code&gt;n&lt;/code&gt; as &amp;ldquo;next match&amp;rdquo; and &lt;code&gt;N&lt;/code&gt; as &amp;ldquo;previous match&amp;rdquo;, with the direction determined by the search operator, &lt;code&gt;/&lt;/code&gt; or &lt;code&gt;?&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The search tool can be used for more than simple literal expressions, it also takes regular expressions.  So &lt;code&gt;/fo.\|bar&lt;/code&gt; will match &lt;code&gt;foo&lt;/code&gt;, &lt;code&gt;fox&lt;/code&gt;, and &lt;code&gt;bar&lt;/code&gt;.  You also can search for lines containing both foo and bar with the expression &lt;code&gt;/.*foo\&amp;amp;.*bar&lt;/code&gt;.  If you want to dig deeper into Vim&amp;rsquo;s regex language, I&amp;rsquo;d recommend typing in &lt;code&gt;:h pattern&lt;/code&gt; to check out the excellent documentation.&lt;/p&gt;
&lt;h3 id=&#34;substitute&#34;&gt;Substitute&lt;/h3&gt;
&lt;p&gt;Search is great, but in many cases what we want to use it for is replacing or acting on each instance.  Vim&amp;rsquo;s search and replace command looks something like &lt;code&gt;:%s/foo/bar/g&lt;/code&gt;, which will replace all occurences of &lt;code&gt;foo&lt;/code&gt; in the document with &lt;code&gt;bar&lt;/code&gt;.  Let&amp;rsquo;s break that down a bit.  &lt;code&gt;:s&lt;/code&gt; (substitute) is Vim&amp;rsquo;s search and replace command.  By default it only works on the current line, so in order to get it to act on the whole document I prepended the &lt;code&gt;%&lt;/code&gt; character, which sets the range to include everything.  If you want a smaller range, you can select the text you want to act on in visual mode. Typing &lt;code&gt;:&lt;/code&gt; will then preload the range into the command area.  Substitute takes an expression in the form &lt;code&gt;/&amp;lt;search expression&amp;gt;/&amp;lt;replace string&amp;gt;/&amp;lt;modifiers&amp;gt;&lt;/code&gt;  where search expression defines the search, replace string is the text to substitute in, and modifiers are single letter arguments that change the behavior.  By default only the first instance of an expression per line is substituted, so I added the &lt;code&gt;g&lt;/code&gt; modifier to tell Vim to substitute all instances of the search expression on a line.  Other useful modifiers are &lt;code&gt;i&lt;/code&gt;, which makes the search case insensitive, and &lt;code&gt;c&lt;/code&gt; which has Vim prompt for confirmation before substituting each instance. Confirmation is helpful if you want to change most but not all occurences of a phrase. One useful behavior of substitute to be aware of: If you leave the search expression blank, it reuses your last search.  So if you&amp;rsquo;ve been playing around with a regex to get the right expression, once you get it right you can type &lt;code&gt;:%s//&amp;lt;replacement&amp;gt;/g&lt;/code&gt;, and it will replace all instances, without forcing you to retype your complicated regex.&lt;/p&gt;
&lt;p&gt;Finally, it&amp;rsquo;s worth noting that search plays nicely with Vim&amp;rsquo;s &lt;a href=&#34;http://benmccormick.org/2014/07/02/learning-vim-in-2014-vim-as-language/&#34;&gt;composable actions&lt;/a&gt;, and you can use it as a motion command with &lt;code&gt;y&lt;/code&gt;, &lt;code&gt;c&lt;/code&gt;, &lt;code&gt;d&lt;/code&gt; or other actions.  For instance &lt;code&gt;d/foo&lt;/code&gt; will delete all text up to the next occurence of foo in the document. &lt;code&gt;y?foo&lt;/code&gt; will yank all text backwards to the previous occurence of foo in the document.&lt;/p&gt;
&lt;h3 id=&#34;inline-searching&#34;&gt;Inline Searching&lt;/h3&gt;
&lt;p&gt;Along with the primary search and substitute commands, Vim has other specialty searching tools.  One of these is its &lt;code&gt;f&lt;/code&gt; and &lt;code&gt;t&lt;/code&gt; commands. &lt;code&gt;f&amp;lt;char&amp;gt;&lt;/code&gt; moves to a single character on the current line.  While less powerful than &lt;code&gt;/&lt;/code&gt;, this can be super useful because of its quick composability and guarantee of not moving out of the current scope.  It&amp;rsquo;s really easy to type &lt;code&gt;cf)&lt;/code&gt; to delete through the end of the parentheses.  &lt;code&gt;t&lt;/code&gt; works similarly, but is non-inclusive, so you can use &lt;code&gt;ct)&lt;/code&gt; to delete everything up to and not including the parentheses.  I remember it as &amp;ldquo;change find character&amp;rdquo; and &amp;ldquo;change to character&amp;rdquo; respectively.  Like &lt;code&gt;/&lt;/code&gt;, these commands support backwards and repeated search.  &lt;code&gt;F&lt;/code&gt; and &lt;code&gt;T&lt;/code&gt; search backwards on the current line, and &lt;code&gt;;&lt;/code&gt; and &lt;code&gt;,&lt;/code&gt; are the default commands for &amp;ldquo;next match&amp;rdquo; and &amp;ldquo;previous match&amp;rdquo; respectively.&lt;/p&gt;
&lt;h3 id=&#34;cross-file-searching-with-vimgrep-and-grep&#34;&gt;Cross-file searching with vimgrep and grep&lt;/h3&gt;
&lt;p&gt;Searching within a file is nice, but what if you want to search in multiple files?  Vim provides 2 commands for that.  The first, &lt;code&gt;:vimgrep&lt;/code&gt;, uses Vim&amp;rsquo;s internal regex engines to search across multiple files. You could for instance type &lt;code&gt;:vimgrep /function/i ./*.js&lt;/code&gt; to search all Javascript files in the current directory for the &amp;ldquo;function&amp;rdquo; keyword.  You&amp;rsquo;d then be able to loop through them using the &lt;code&gt;:ln&lt;/code&gt; and &lt;code&gt;:lp&lt;/code&gt; commands.&lt;/p&gt;
&lt;p&gt;The second command, &lt;code&gt;:grep&lt;/code&gt;, integrates with an external search application (grep by default), to do the searching.  The advantage of the first is that it&amp;rsquo;s portable and will be available anywhere and everywhere that Vim is.  But generally external tools are going to be faster than Vim&amp;rsquo;s internal search engine.  Grep for instance is faster than vimgrep.  I personally use the external tool &lt;a href=&#34;http://beyondgrep.com/&#34;&gt;ack&lt;/a&gt; which is faster than grep.  Regardless though, Vim has support for whatever approach you choose to take.&lt;/p&gt;
&lt;h3 id=&#34;cross-file-replace-with-the-arglist&#34;&gt;Cross-file replace with the arglist&lt;/h3&gt;
&lt;p&gt;Up till now we&amp;rsquo;ve mostly been dealing with tasks that Vim has good answers for.  If you want to do a search and replace across multiple files in Vim though, you end up in some of the more esoteric parts of Vim-land.  In order to do a search and replace across multiple files in Vim, you need to first define a set of files to edit, and then run the replace command.  Unfortunately there is no way in Vim to cleanly do this all in a single command.  Instead you must pull your list of files from one of 3 places, the arglist, the buffer list, or the window list.  The arglist is by default the files that you specified to open when you initially opened Vim, the buffer list is your list of currently opened buffers, and the window list is the list of files in currently open windows.  Since you probably don&amp;rsquo;t want to have to open or view all the files that you want to run a search/replace on, and you may want to have files open or visible without running a replace on them, the arglist is the list of choice for replacements.  Vim allows you to edit the contents of the arglist at any time using the &lt;code&gt;:argadd&lt;/code&gt; and &lt;code&gt;argdelete&lt;/code&gt; commands.  So to replace &lt;code&gt;foo&lt;/code&gt; with &lt;code&gt;bar&lt;/code&gt; for all javascript files in the current directory you might type something like.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-vimscript&#34; data-lang=&#34;vimscript&#34;&gt;:argd * &amp;quot;Clear arglist
:arga ./*.js  &amp;quot;Add javascript files
:argdo %s/foo/bar/g &amp;quot;Substitute on each file
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;argdo&lt;/code&gt; is the command to execute a command across all files in the arglist.  &lt;code&gt;bufdo&lt;/code&gt;, &lt;code&gt;tabdo&lt;/code&gt;, and &lt;code&gt;windo&lt;/code&gt; work the same way for every &amp;ldquo;open buffer&amp;rdquo;, &amp;ldquo;active window in each tab&amp;rdquo;, and &amp;ldquo;window in the current tab&amp;rdquo; respectively. Personally I find this all to be a pain.  A single command that let you specify an action and a range to run it on like &lt;code&gt;:do &#39;%s/foo/bar/g&#39; ./*.js&lt;/code&gt; would make plenty of sense.  But since that doesn&amp;rsquo;t exist, it&amp;rsquo;s worth at least knowing that the arglist is there, and being able to resort to it if necessary.&lt;/p&gt;
&lt;h3 id=&#34;the-power-of-search&#34;&gt;The Power Of Search&lt;/h3&gt;
&lt;p&gt;Most people start out using Vim knowing that they can move around with &lt;em&gt;hjkl&lt;/em&gt; and switch between files with &lt;code&gt;:e &amp;lt;filename&amp;gt;&lt;/code&gt; as they learn more they grow their toolbox. Search is a great tool for moving quickly around text in Vim, and for powerfully making big edits.  Searching allows you to allow your brain to focus on the big picture, rather than remembering exactly where each piece of code or content is located. Like everything else in Vim, it&amp;rsquo;s a tool that you can combine with other tools to create powerful workflows.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&#34;more-resources&#34;&gt;More Resources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;http://vimcasts.org/episodes/operating-on-search-matches-using-gn/&#34;&gt;Vimcasts&lt;/a&gt; has a nice piece on the &lt;code&gt;gn&lt;/code&gt; command, an alternative to &lt;code&gt;n&lt;/code&gt; that lets you select the next search match in visual mode&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;http://vim.wikia.com/wiki/Search_and_replace&#34;&gt;Vim&amp;rsquo;s wiki&lt;/a&gt; also has a nice writeup of the &lt;code&gt;:substitute&lt;/code&gt; command, with lots of examples and details.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Learning Vim in 2014: Copy and Paste the Vim Way</title>
      <link>https://benmccormick.org/2014/07/27/180000.html</link>
      <pubDate>Sun, 27 Jul 2014 19:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2014/07/27/180000.html</guid>
      <description>&lt;p&gt;If you&amp;rsquo;ve been following &lt;a href=&#34;http://benmccormick.org/tag/learning-vim-in-2014/&#34;&gt;my series on Vim&lt;/a&gt;, it should be clear now that Vim has a pretty clear philosophy of how text editing should work. It&amp;rsquo;s based on the Unix philosophy of small composable tools, and doesn&amp;rsquo;t necessarily match up with the conventions that other editors use for common commands.  So it&amp;rsquo;s probably not surprising that Vim has its own way of handling copy and paste operations, and in fact doesn&amp;rsquo;t even use those terms.  Vim&amp;rsquo;s copy and paste handling is minimalist, composable, and powerful, but most people take some time to adjust to it.  I&amp;rsquo;m going to walk through the basics here, along with a few advanced features that are worth knowing about.&lt;/p&gt;
&lt;p&gt;The primary Vim commands for copying something are &lt;code&gt;y&lt;/code&gt; (yank) which acts like most people&amp;rsquo;s view of copy, and the delete/substitute commands &lt;code&gt;d&lt;/code&gt; (delete),&lt;code&gt;c&lt;/code&gt; (change), &lt;code&gt;x&lt;/code&gt; (single character delete), and &lt;code&gt;s&lt;/code&gt; (substitute), which unintuitively all act like the more common concept of &amp;ldquo;cut&amp;rdquo;.  These can be &lt;a href=&#34;http://benmccormick.org/2014/07/16/learning-vim-in-2014-vim-as-art/&#34;&gt;composed with motion commands to select different regions&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Any Vim command that deletes text will also save a copy of that text unless you specifically tell it not too.  The idiomatic Vim method of deleting without copying is &lt;code&gt;&amp;quot;_d&lt;/code&gt;, which probably sounds bizarre.  We&amp;rsquo;ll come back to that later, and you&amp;rsquo;ll see that it makes sense in the bigger scheme of Vim&amp;rsquo;s copy and paste system.&lt;/p&gt;
&lt;p&gt;The basic Vim commands for paste are &lt;code&gt;p&lt;/code&gt; (put) which pastes after of the current character/line and &lt;code&gt;P&lt;/code&gt; which pastes before the current character/line.  Vim auto detects whether you&amp;rsquo;ve yanked text on a line by line basis or a character by character basis, and pastes accordingly. Basically, if you select only full lines it will paste line by line and not break on the cursor position, if you select any partial lines it will paste at the character level, starting or ending at the current cursor location.  Note that &lt;code&gt;p&lt;/code&gt; also works in visual mode, where it will replace the current selection.&lt;/p&gt;
&lt;p&gt;All of this leads to a very common annoyance for new Vim users.  They&amp;rsquo;re editing a document and yank some text.  Then they go to a new location, delete a few lines, and hit &lt;code&gt;p&lt;/code&gt; to replace them with the copied text.  Do you see the problem?  The text that is &amp;ldquo;put&amp;rdquo; is not what they originally yanked, but instead it&amp;rsquo;s the contents of their last delete action. Obviously this can be worked around by changing the order of the actions, but it&amp;rsquo;s frustrating to users who are used to being able to easily delete without blowing away their paste action.  Even more frustrating is when an experienced Vim user comes by and tells them the answer to their problem is to just type &lt;code&gt;&amp;quot;0p&lt;/code&gt; instead. Which will in fact put the correct text. So what&amp;rsquo;s going on with the weird syntax for these basic action?&lt;/p&gt;
&lt;h4 id=&#34;registers&#34;&gt;Registers&lt;/h4&gt;
&lt;p&gt;What we&amp;rsquo;re missing is a clear understanding of how Vim handles copy and paste operations.  So let&amp;rsquo;s clarify.  Unlike most modern systems, which have a clipboard that holds a single value, Vim can store the values of yank and delete commands in one of many registers.  It has 26 normal registers, which correspond to the letters of the alphabet, and several &amp;ldquo;special&amp;rdquo; registers.  One of those special registers is the default register, which is where yank and delete commands store their content by default.  Other registers can be accessed with the &lt;code&gt;&amp;quot;&amp;lt;char&amp;gt;&lt;/code&gt; prefix that we&amp;rsquo;ve already seen.  So in the above example, the text from the initial example is moved into the default register, and then replaced there by the deleted text.  But it remains in the 0 register, which always points to the last &amp;ldquo;yanked&amp;rdquo; text, ignoring text gained by deleting.&lt;/p&gt;
&lt;p&gt;The 26 alphabetical registers serve as great &amp;ldquo;medium term&amp;rdquo; storage.  You can use them to yank something that you want to have around for a while, and then put it in a few different places, even if you&amp;rsquo;re yanking and deleting other things in the meantime.  These will even persist across sessions as long as you have the &lt;code&gt;nocompatible&lt;/code&gt; option set in your vimrc file.  However if you overwrite one, there&amp;rsquo;s no easy way to get it back.&lt;/p&gt;
&lt;p&gt;One cool feature of registers is the built in ability to append to the end of them.  If you want to add text to an existing register, for instance if you missed part of the text you wanted to yank, you can do so by capitalizing the register.  So if you had deleted a line and put it in the &lt;code&gt;a&lt;/code&gt; register with &lt;code&gt;&amp;quot;add&lt;/code&gt;, but meant to include a second line, you could then delete the next line and append it to the register with &lt;code&gt;&amp;quot;Add&lt;/code&gt;. &lt;code&gt;&amp;quot;ap&lt;/code&gt; would then put the 2 lines back into the document.&lt;/p&gt;
&lt;h4 id=&#34;special-registers&#34;&gt;Special Registers&lt;/h4&gt;
&lt;p&gt;In addition to the alphabetical registers, there are several &lt;em&gt;special registers&lt;/em&gt; that are worth knowing about.  I already mentioned the default register, which most Vim users know about, even if they don&amp;rsquo;t understand exactly how registers work.  Other important registers are the clipboard register, the black hole register, and the numbered registers.&lt;/p&gt;
&lt;p&gt;If you have to learn one special register, learn the clipboard register.  One of the first things people notice about copy and paste in Vim is that it doesn&amp;rsquo;t interact nicely with other applications&#39; copy and paste by default.  If you yank a line of text in Vim, it&amp;rsquo;s not added to the system clipboard.  If you copy some code from Stack Overflow and try to paste it in Vim with &lt;code&gt;p&lt;/code&gt;, it won&amp;rsquo;t work &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.  But, since we know about registers, it makes sense that the default register might not be mapped to the clipboard, which we don&amp;rsquo;t want getting blasted away everytime we delete a character.&lt;/p&gt;
&lt;p&gt;Vim isn&amp;rsquo;t completely disconnected from the system clipboard though.  The clipboard register &lt;code&gt;+&lt;/code&gt; is Vim&amp;rsquo;s proxy to your system clipboard.  So &lt;code&gt;&amp;quot;+y&amp;lt;motion&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;quot;+p&lt;/code&gt; act like traditional copy and paste.  Your version of Vim does have to be compiled with clipboard support in order to use the &lt;code&gt;+&lt;/code&gt; register. You can check to see if you have clipboard support with &lt;code&gt;:echo has(&#39;clipboard&#39;).&lt;/code&gt;&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; On OSX you can use MacVim to get clipboard support, since the default version of Vim shipped with OSX is not compiled with it.  On other operating systems you&amp;rsquo;ll have to investigate the easiest way to install with clipboard support if your version doesn&amp;rsquo;t have it.  It should be enabled for most modern mainstream distributions.&lt;/p&gt;
&lt;p&gt;Another register to quickly note is the black hole register &lt;code&gt;_&lt;/code&gt;.  The black hole register, as you would expect, doesn&amp;rsquo;t retain what&amp;rsquo;s passed to it.  So &lt;code&gt;&amp;quot;_y&lt;/code&gt; and &lt;code&gt;&amp;quot;_p&lt;/code&gt; are no-ops, and &lt;code&gt;&amp;quot;_d&lt;/code&gt; is &amp;ldquo;true delete&amp;rdquo;, as opposed to the delete commands default &amp;ldquo;cut&amp;rdquo; like behavior.  Of course since most people don&amp;rsquo;t use all 26 alphabetical registers, you can also achieve effective true delete by deleting to any unused register.&lt;/p&gt;
&lt;p&gt;Finally, the number keys also have special register functionality.  You can&amp;rsquo;t yank text directly to a numbered register.  Instead the &lt;code&gt;0&lt;/code&gt; register contains the last yanked text, and the &lt;code&gt;1&lt;/code&gt; through &lt;code&gt;9&lt;/code&gt; registers contain the last 9 deleted chunks of text.  This feature is a cool idea, but unfortunately the implementation is inconsistent and a bit weird.  For one thing the distinction between yanked and deleted text seems arbitrary, and since they act the same in other ways, puts an added cognitive load on the user to remember which one they used.  Secondly, for whatever reason, deletions that span less than a line get special behavior.  If you delete these to an alphabetical register, they&amp;rsquo;re saved to &lt;code&gt;&amp;quot;1&lt;/code&gt; just like any other delete.  But if you delete them to the default register, they&amp;rsquo;re saved to &lt;code&gt;&amp;quot;-&lt;/code&gt; and not put in &lt;code&gt;&amp;quot;1&lt;/code&gt;.  The logic is complicated enough that the numbered registers become tough to use in day to day tasks, and I&amp;rsquo;ll have to agree with Drew Neil in labeling them one of Vim&amp;rsquo;s &lt;a href=&#34;http://vimcasts.org/blog/2013/11/registers-the-good-the-bad-and-the-ugly-parts/&#34;&gt;&amp;ldquo;bad parts.&amp;quot;&lt;/a&gt;&lt;/p&gt;
&lt;h4 id=&#34;macros&#34;&gt;Macros&lt;/h4&gt;
&lt;p&gt;One last important thing to know about registers is that along with being used for copy and paste, they serve as a place to save macros, Vim&amp;rsquo;s reusable command language.  You can save a macro by typing &lt;code&gt;q&amp;lt;register key&amp;gt;&amp;lt;commands&amp;gt;q&lt;/code&gt;, and the macro will be saved to the register.  Like yank and delete, capitalizing the register name will let you append to the register instead of replacing it. So there&amp;rsquo;s a few things you should know about that.  One, if you use macros, don&amp;rsquo;t save macros to the same registers that you use for copy and paste.  If you use the &lt;code&gt;y&lt;/code&gt; register a lot for the convenience of &lt;code&gt;&amp;quot;yy&amp;lt;motion&amp;gt;&lt;/code&gt;, don&amp;rsquo;t use &lt;code&gt;qy&lt;/code&gt; to save your macro unless you&amp;rsquo;re ok with it being blown away by your next yank.  Two, the sharing of registers allows you to copy text to use as a macro.  So if you for instance wanted to have a file with a list of common operations, it would be easy to go to that file, copy a line, and then execute it as a macro.  This isn&amp;rsquo;t the first thing most people will want to do, but it illustrates the power and flexibility that come when you start combining Vim&amp;rsquo;s tools.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&#34;more-resources&#34;&gt;More Resources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;For a more in depth look at Vim&amp;rsquo;s special registers, including a bunch I didn&amp;rsquo;t cover here, you can check out this great &lt;a href=&#34;http://blog.sanctum.geek.nz/advanced-vim-registers/&#34;&gt;roundup&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;http://vimcasts.org/categories/copy-and-paste/&#34;&gt;Vimcasts&lt;/a&gt; has a whole series of posts on copy and paste in Vim.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;div class=&#34;footnotes&#34;&gt;
&lt;ol&gt;
    &lt;li class=&#34;footnote&#34; id=&#34;fn:1&#34;&gt;
        &lt;p&gt;
        Of course some people would probably see that as a feature, not a bug
    	&lt;a href=&#34;#fnref:1&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li class=&#34;footnote&#34; id=&#34;fn:2&#34;&gt;
        &lt;p&gt;
        Thanks to schweinschmeisser on Reddit for reminding me to add a way to check for support.
    	&lt;a href=&#34;#fnref:2&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>One Day Left In Practical Vim Giveaway</title>
      <link>https://benmccormick.org/2014/07/24/185545.html</link>
      <pubDate>Thu, 24 Jul 2014 19:55:45 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2014/07/24/185545.html</guid>
      <description>&lt;p&gt;My practical Vim giveaway ends tomorrow,  Friday July 25th at midnight.  If you haven&amp;rsquo;t subscribed or tweeted to win yet, now is the best time, so go for it!&lt;/p&gt;
&lt;h3 id=&#34;giveaway-details&#34;&gt;Giveaway Details&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;vim.jpg&#34; alt=&#34;Practical Vim&#34;&gt;&lt;/p&gt;
&lt;p&gt;As a thanks for all of the great interest and feedback I&amp;rsquo;ve gotten for my posts on Vim recently, I&amp;rsquo;m going to be giving away 2 copies of Drew Neil&amp;rsquo;s book, Practical Vim.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://www.amazon.com/gp/product/1934356980/ref=as_li_tl?ie=UTF8&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=1934356980&amp;amp;linkCode=as2&amp;amp;tag=benmccormicko-20&amp;amp;linkId=FE3JFKHYVRYCUOVS&#34;&gt;Practical Vim&lt;/a&gt; is the best resource on Vim I&amp;rsquo;ve found.  Drew Neil is the creator of &lt;a href=&#34;http://vimcasts.org/&#34;&gt;vimcasts&lt;/a&gt;, the popular online Vim site.  And this book is his attempt to explain what makes Vim special.  It&amp;rsquo;s bursting cover to cover with practical tips and tricks to help you become a more efficient writer and developer.  Reading it helped me understand the philosophy behind Vim, and I would recommend it for anyone who uses Vim or thinks they might want to.  There&amp;rsquo;s a reason I recommend it as the Vim resource on my &lt;a href=&#34;http://benmccormick.org/readinglist/&#34;&gt;reading list&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So how do you get a copy?  There are a few ways&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Follow &lt;a href=&#34;http://twitter.com/benmccormickorg&#34;&gt;@benmccormickorg&lt;/a&gt; on Twitter&lt;/li&gt;
&lt;li&gt;Subscribe to my &lt;a href=&#34;http://eepurl.com/WFYon&#34;&gt;mailing list feed&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Tweet a link to one of my &lt;em&gt;Learning Vim&lt;/em&gt; posts, with the hashtag &lt;strong&gt;#learningvim&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You can accumulate up to 3 entries by doing each of the above (I won&amp;rsquo;t count multiple tweets for the 3rd).  The giveaway will end July 25th, at which time I&amp;rsquo;ll pick 2 winners at random, and get in touch through Twitter or email.  If you have questions or concerns, feel free to speak up in the comments. Otherwise, go subscribe and win a chance to get a great book for free!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Learning Vim in 2014: Getting More from Vim with Plugins</title>
      <link>https://benmccormick.org/2014/07/21/055000.html</link>
      <pubDate>Mon, 21 Jul 2014 06:50:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2014/07/21/055000.html</guid>
      <description>&lt;p&gt;It&amp;rsquo;s impossible to design a tool that fits everyone&amp;rsquo;s workflow perfectly.  No matter how many cases you hit, somebody will want to do something you don&amp;rsquo;t support, will find your solution for their problem confusing, or they&amp;rsquo;ll try to use your tool in a way you never imagined. Vim tries to deal with situations like that in 2 ways.  First by making it easy to &lt;a href=&#34;http://benmccormick.org/2014/07/14/learning-vim-in-2014-configuring-vim/&#34;&gt;configure&lt;/a&gt;, and second by making it easy to extend.  Extending Vim happens through plugins. &lt;span class=&#34;aside&#34;&gt;
&lt;img src=&#34;xkcdworkflow.png&#34; alt=&#34;xkcd workflow&#34;&gt;
&lt;/span&gt;
Vim plugins allow you to enhance, change, or add to Vim&amp;rsquo;s existing behaviors.  They&amp;rsquo;re a powerful tool, and a key part of what has helped Vim remain relevant for 23 years, even as the computing world has changed dramatically around it.  They allow Vim to support languages that didn&amp;rsquo;t exist the last time its core was updated, handle niche use cases that would never get solutions in the main Vim distribution, and also allow for powerful new features that benefit all users.&lt;/p&gt;
&lt;p&gt;Your key focus when it comes to Vim plugins should be identifying your needs and finding plugins to fit them.  Don&amp;rsquo;t just toss every plugin you see recommended somewhere into your .vim/bundle folder.  Plugins have costs; they slow down file loads, can fill up the key mapping space, and add complexity for users.  But they&amp;rsquo;re also extremely powerful, and I recommend that everyone who controls their development environment think about using at least a few.&lt;/p&gt;
&lt;h3 id=&#34;plugin-management-hello-vundle&#34;&gt;Plugin Management: Hello Vundle&lt;/h3&gt;
&lt;p&gt;Before you install anything, you&amp;rsquo;re going to need a strategy for managing your plugins.  Plugin management for Vim has a bit of a troubled history.  There&amp;rsquo;s never been an official plugin management solution, and unlike Sublime Text&amp;rsquo;s Package Control, there wasn&amp;rsquo;t a simple, easy to use solution that the community standardized.  Instead, plugins were initially just placed into the .vim folder or elsewhere and then sourced in ~/.vimrc.  To allow for download or installation, authors used a variety of compression formats, including a Vim specific Vimball format.  Early efforts to standardize a process didn&amp;rsquo;t go particulary well.&lt;/p&gt;
&lt;p&gt;That changed with the rise of Github and Tim Pope&amp;rsquo;s &lt;a href=&#34;https://github.com/tpope/vim-pathogen&#34;&gt;Pathogen&lt;/a&gt;.  Pathogen was the first plugin manager to make it relatively simple to include new plugins, by encouraging a standard directory format and installation process (using git repositories).  It began a standardization process that now means pretty much any modern Vim plugin can be installed with Pathogen without modification.&lt;/p&gt;
&lt;p&gt;Despite Pathogen&amp;rsquo;s historical significance, in 2014 you should use &lt;a href=&#34;https://github.com/gmarik/Vundle.vim&#34;&gt;Vundle&lt;/a&gt;, not Pathogen, to manage your plugins.  Vundle is an easy to use plugin manager that is compatible with the Pathogen format.  Vundle improves on Pathogen in several ways.  It allows you to list the plugins you want to use in your vimrc file, then will pull them down and install them for you.  So adding and removing plugins is just a configuration change, and it&amp;rsquo;s always easy to see which ones you&amp;rsquo;re currently using.  It makes it easy to pull plugins from a variety of sources, but optimizes for Github, and Vim.org.  Since roughly 99% of plugins that most users will need are available from one of those sources, this is extremely convenient.  You can find full documentation for using Vundle in its &lt;a href=&#34;https://github.com/gmarik/Vundle.vim&#34;&gt;Github repo&lt;/a&gt;, but trust me, it&amp;rsquo;s the best option out there for 99% of users.&lt;/p&gt;
&lt;h3 id=&#34;what-can-plugins-do-for-you&#34;&gt;What Can Plugins do for you?&lt;/h3&gt;
&lt;p&gt;Before you start installing plugins, it&amp;rsquo;s worth thinking about what you need from them.  There are a few main purposes for using plugins.  I&amp;rsquo;m including a few examples of each to get you started as you figure out which plugins make sense for you.&lt;/p&gt;
&lt;h4 id=&#34;let-vim-get-your-files-in-order&#34;&gt;Let Vim Get Your Files In Order&lt;/h4&gt;
&lt;p&gt;File management plugins are some of the most important plugins you can use with Vim.  Vim&amp;rsquo;s built-in file management is pretty weak in some ways compared to editors like Sublime Text and TextMate.  Plugins can fill that gap.  The plugins listed below show several approaches to file management.  There&amp;rsquo;s plenty of overlap in functionality here, but they&amp;rsquo;re all worth trying to see which ones fit your style.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/kien/ctrlp.vim&#34;&gt;CtrlP&lt;/a&gt; is probably my most used Vim plugin.  It provides fuzzy finding capabilities for Vim, to allow you to search for files in a similar way to Sublime Text&amp;rsquo;s &amp;ldquo;Go To Anything&amp;rdquo; bar.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/mileszs/ack.vim&#34;&gt;Ack.vim&lt;/a&gt; and &lt;a href=&#34;https://github.com/rking/ag.vim&#34;&gt;Ag.vim&lt;/a&gt; are plugins to connect Vim with Ack and Ag respectively.  If you&amp;rsquo;re not using one of these tools for code search, you &lt;a href=&#34;http://benmccormick.org/2013/11/25/a-look-at-ack/&#34;&gt;really should be&lt;/a&gt;.  They&amp;rsquo;re much faster than grep or an IDE&amp;rsquo;s built in search.  These plugins provide seamless integration for each within Vim, allowing you to easily jump to the code you&amp;rsquo;re searching on, opening new tabs or splits if you like.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/Shougo/unite.vim&#34;&gt;Unite.vim&lt;/a&gt; is an interesting attempt to combine the functionality of plugins like ctrlp, ack.vim and others into a single &amp;ldquo;omnisearch&amp;rdquo; interface.  I personally found it a bit unintuitive and poorly documented, but some people &lt;a href=&#34;http://www.codeography.com/2013/06/17/replacing-all-the-things-with-unite-vim.html&#34;&gt;swear by it&lt;/a&gt;. If you are able to make sense of it, it&amp;rsquo;s certainly a great concept to pull in related functionality into a single interface.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/scrooloose/nerdtree&#34;&gt;The NERDTree&lt;/a&gt; is one of the most popular Vim plugins out there.  It provides a more traditional side-drawer style navigation interface to complement Vim&amp;rsquo;s other navigation options.  I personally prefer a &amp;ldquo;search over specifying&amp;rdquo; navigation style, so ctrlp and ack.vim work better for me.  But I keep NERDTree around for looking at other people&amp;rsquo;s code in new projects, when I want to look around a directory to see what&amp;rsquo;s available and how it&amp;rsquo;s structured before diving in.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/tpope/vim-projectionist&#34;&gt;Projectionist.vim&lt;/a&gt; is something I&amp;rsquo;ve just begun to look into.  It&amp;rsquo;s an interesting approach by Tim Pope to provide a more intuitive way to navigate structured projects.  Rather than fuzzy finding or sidebars, Projectionist invites you to create categories of files that you can open files from (for instance  model, view and controller files in a BackboneJS project).  This gives you the simplicity of traditional Vim file path opens while removing some of the memorization and clutter from the process.  Projectionist also allows you to specify alternate files for each file. That allows you to, for instance, jump quickly from a file to its unit test file.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;building-on-vims-built-in-language&#34;&gt;Building On Vim&amp;rsquo;s Built In Language&lt;/h4&gt;
&lt;p&gt;Another interesting class of Vim plugins are plugins that extend Vim&amp;rsquo;s existing language concepts.  In my past few posts I&amp;rsquo;ve looked at how Vim is intended to be used by &lt;a href=&#34;http://benmccormick.org/2014/07/02/learning-vim-in-2014-vim-as-language/&#34;&gt;combining composable commands with motions and text objects&lt;/a&gt;, then efficiently &lt;a href=&#34;http://benmccormick.org/2014/07/16/learning-vim-in-2014-vim-as-art/&#34;&gt;repeating that process when possible&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/tpope/vim-surround&#34;&gt;Surround.vim&lt;/a&gt; is another plugin by Tim Pope.  It provides an extra command to use with Vim&amp;rsquo;s built in text objects. That command, &lt;code&gt;ys&lt;/code&gt; allows you to surround a text object with some sort of enclosing tag. So &lt;code&gt;ysiw&#39;&lt;/code&gt; surrounds the current word with &lt;code&gt;&#39;&lt;/code&gt;, and &lt;code&gt;ysip&amp;lt;div class=&amp;quot;example&amp;quot;&amp;gt;&lt;/code&gt; surrounds the current paragraph with &lt;code&gt;&amp;lt;div class=&amp;quot;example&amp;quot;&amp;gt;...&amp;lt;/div&amp;gt;&lt;/code&gt; tags.  There&amp;rsquo;s also a separate command to replace surrounding characters with different ones.  It&amp;rsquo;s extremely useful, especially for HTML editing and quoting.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/tpope/vim-commentary&#34;&gt;commentary.vim&lt;/a&gt; adds a &amp;ldquo;commenting&amp;rdquo; action, &lt;code&gt;gc&lt;/code&gt; that can be used with existing motions.  So &lt;code&gt;gcc&lt;/code&gt; comments out the current line, &lt;code&gt;gcG&lt;/code&gt; comments out the remainder of a file, and so on.  This is yet another Tim Pope plugin.  I promise I&amp;rsquo;m not trying to make up for recommending Vundle over Pathogen, the guy has just been prolific.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/tpope/vim-repeat&#34;&gt;Repeat.vim&lt;/a&gt; is one final Tim Pope plugin for now.  Repeat allows you to extend the &lt;code&gt;.&lt;/code&gt; command to work with user created commands.  It works with surround and commentary out of the box, but you can also set it up to work with your own commands. &lt;a href=&#34;http://benmccormick.org/2014/07/16/learning-vim-in-2014-vim-as-art/&#34;&gt;The . command is one of the most important Vim commands&lt;/a&gt;, so being able to use it in more situations is definitely a win.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/kana/vim-textobj-user&#34;&gt;vim-text-obj-user&lt;/a&gt; is an interesting project to make it easy to create plugins that define custom text objects which then can be used with Vim commands like any other text object.  If that sounds scary to you, you can also take a look at the &lt;a href=&#34;https://github.com/kana/vim-textobj-user/wiki&#34;&gt;list&lt;/a&gt; of plugins already built with the project, and use any that will be useful to you.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;img alt=&#34;Vim side by side styles&#34; class=&#34;full-width&#34; src=&#34;vimvisuals.png&#34;&gt;
&lt;h4 id=&#34;help-vim-look-good&#34;&gt;Help Vim Look Good&lt;/h4&gt;
&lt;p&gt;One of the best uses for plugins is making Vim a bit easier on the eyes. We can do a lot to change Vim&amp;rsquo;s default look and feel.  For instance the screenshot above shows what MacVim looks like with and without loading my ~/.vimrc file and plugins.  If you&amp;rsquo;re a writer or developer, you may be looking at Vim for as much as 8-10 hours a day.  So make it something you&amp;rsquo;re happy to look at.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Syntax highlighting plugins are one of the main things you can use to make your code easier to read.  Vim packages syntax highlighting for many common languages, but for less mainstream languages you&amp;rsquo;ll need to download plugins to get syntax highlighting.  These plugins often may contain other niceties for the language, like syntax checking or support for compiling from within Vim.  For instance I use plugins for &lt;a href=&#34;https://github.com/groenewege/vim-less&#34;&gt;Less&lt;/a&gt;, &lt;a href=&#34;https://github.com/kchmck/vim-coffee-script&#34;&gt;CoffeeScript&lt;/a&gt;, and &lt;a href=&#34;https://github.com/plasticboy/vim-markdown&#34;&gt;Markdown&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Colorschemes are also an important part of helping Vim look its best.  Most distributions of Vim bundle several colorschemes, but the most popular ones come as plugins.  If you&amp;rsquo;re somebody who needs to know that somebody else has sweated the details of the tools you use so that you don&amp;rsquo;t have to, I recommend &lt;a href=&#34;http://ethanschoonover.com/solarized&#34;&gt;Solarized&lt;/a&gt;, a color scheme based on the relationships between different colors and designed to echo the readability of words on paper.  If you like to try different things and have more options, consider looking at &lt;a href=&#34;https://github.com/chriskempson/base16&#34;&gt;Base16&lt;/a&gt;, a project to standardize color scheme creation for multiple editors.  The advantage of both of these schemes is that they&amp;rsquo;re available for pretty much any editor or tool you&amp;rsquo;d want to use alongside or in place of Vim.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/reedes/vim-thematic&#34;&gt;Thematic&lt;/a&gt; is a tool to allow you to manage your visual schemes.  So if you like to use different color schemes or fonts in different situations, Thematic can make that easy. You can define a set of &amp;ldquo;themes&amp;rdquo;, and then switch between them whenever you feel like it.  As somebody who uses Vim for both writing and programming, it&amp;rsquo;s nice to be able to use different themes for different situations.  I currently use Solarized for code, and the Pencil theme for writing.  Thematic and Pencil are two of a &lt;a href=&#34;http://wynnnetherland.com/journal/reed-esau-s-growing-list-of-vim-plugins-for-writers&#34;&gt;wide variety of plugins for writers&lt;/a&gt; that Reed Esau has written.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/bling/vim-airline&#34;&gt;Airline&lt;/a&gt; is a plugin to pretty up your status bar.  It creates the nice triangular effects in the image above, and integrates with other plugins to show helpful information in the status bar.  It does require modified fonts to use though, so you&amp;rsquo;ll need to have pretty full control of the system you&amp;rsquo;re on to use this one.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;help-vim-understand-your-code&#34;&gt;Help Vim Understand Your Code&lt;/h4&gt;
&lt;p&gt;Vim is not an IDE.  By default it doesn&amp;rsquo;t understand much about code, and very little about specific languages.  It offloads that knowledge to the operating system, through things like &lt;code&gt;:make&lt;/code&gt; and &lt;code&gt;ctags&lt;/code&gt;, and to plugins.  Here are a few plugins that can help make Vim a bit more &amp;ldquo;code aware&amp;rdquo;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/scrooloose/syntastic&#34;&gt;Syntastic&lt;/a&gt; is a syntax checking plugin for Vim that integrates with external syntax checkers to provide in-editor feedback on your code as you make changes.  For instance, it can integrate with jshint, llvm or javac to provide immediate feedback on a file.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/Valloric/YouCompleteMe&#34;&gt;YouCompleteMe&lt;/a&gt; is a code completion engine for Vim that builds on Vim&amp;rsquo;s built in autocomplete features to offer &amp;ldquo;smart completion&amp;rdquo; for as many situations as possible.  It can integrate with Clang, Jedi, Omnisharp, and Vim&amp;rsquo;s omnicompletion in order to bring smart autocomplete to a variety of languages.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/tpope/vim-fugitive&#34;&gt;Fugitive&lt;/a&gt; and &lt;a href=&#34;https://github.com/jisaacks/GitGutter&#34;&gt;Git-gutter&lt;/a&gt; are 2 plugins that bring Git integration into Vim.  Fugitive provides a wrapper around the Git executable to allow you to easily manage your git actions from within Vim. GitGutter focuses on individual files and lets you see where you&amp;rsquo;ve made uncommited modifications in the current file.  They complement each other well, and are both very useful for heavy Git users.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/Raimondi/delimitMate&#34;&gt;delimitMate&lt;/a&gt; is a simple plugin that removes a huge annoyance by auto inserting matching braces and brackets in a smart, intuitive way.  Lack of auto brace insertion was a big mental hurdle for me coming from Sublime Text.  DelimitMate makes things work the way I expect.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Language specific plugins are another plugin group worth investigating.  There are way too many examples to list here, but one that I use and enjoy is &lt;a href=&#34;http://ternjs.net/&#34;&gt;TernJs&lt;/a&gt;, a code intelligence plugin for Javascript that you can use with something like YouCompleteMe to get the type of IDE style autocompletion that is very rare for Javascript code.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;help-vim-play-nice-with-others&#34;&gt;Help Vim Play Nice With Others&lt;/h4&gt;
&lt;p&gt;Some plugins exist to provide tighter integration between Vim and external programs.  We&amp;rsquo;ve already touched on a few of those, like Ack.vim and Syntastic.  Vim is intended to follow the Unix philosophy of doing one thing well and working well with other programs.  Integration plugins allow for deeper versions of that.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/christoomey/vim-tmux-navigator&#34;&gt;Tmux Navigator&lt;/a&gt; is a must have plugin for &lt;a href=&#34;http://tmux.sourceforge.net/&#34;&gt;Tmux&lt;/a&gt; users.  It allows you to easily move between tmux and Vim splits using a single set of keyboard mappings.  It lets Vim and tmux work together in a completely natural way, without the user having to keep track of where one ends and the other begins.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;http://kapeli.com/dash&#34;&gt;Dash.vim&lt;/a&gt; is an OSX only plugin that provides integration with Dash.app, a documentation manager app for OSX, making it easy to look up library method definitions from within Vim.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;grant-vim-superpowers&#34;&gt;Grant Vim Superpowers&lt;/h4&gt;
&lt;p&gt;The last category of plugins are scripts that allow Vim to do things that are totally different than anything it can do on its own.  These may be features pulled from other editors, or features inspired by Vim but implemented differently than the Vim core.  These can be pretty amazing, but I&amp;rsquo;d be careful with them to start.  You&amp;rsquo;ll want to learn how Vim works before piling a bunch of big extensions on top of it.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/SirVer/ultisnips&#34;&gt;Ultisnips&lt;/a&gt; allows Vim to use Textmate like &amp;ldquo;snippets&amp;rdquo; that allow you to save canned templates of code or text, then insert and modify them whenever you&amp;rsquo;re ready.  If this sounds interesting, I&amp;rsquo;d recommend checking out the recent &lt;a href=&#34;http://vimcasts.org/episodes/meet-ultisnips/&#34;&gt;Vimcast&lt;/a&gt; episodes where Drew explores Ultisnips.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/Lokaltog/vim-easymotion&#34;&gt;EasyMotion&lt;/a&gt; is a plugin that introduces a new type of movement to Vim.  It creates alternative versions of the Vim movements like &lt;code&gt;f&lt;/code&gt; and &lt;code&gt;w&lt;/code&gt; that allow you to find a character or word anywhere on the screen, and specify it by using a key character that temporarily appears on the screen in place of each possible target character.  If that&amp;rsquo;s hard to follow, check out the &lt;a href=&#34;https://camo.githubusercontent.com/d5f800b9602faaeccc2738c302776a8a11797a0e/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f333739373036322f323033393335392f61386539333864362d383939662d313165332d383738392d3630303235656138333635362e676966&#34;&gt;demo&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id=&#34;more-resources&#34;&gt;More Resources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;http://vimawesome.com/&#34;&gt;VimAwesome&lt;/a&gt; is a recent project to collect popular Vim plugins in a beautiful, searchable format. It lists some categories similar to what I have above and sorts plugins by popularity.  It seems to pull rankings based on mentions in Github dotfiles, which is a creative and useful way of ranking plugins.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;http://vimcasts.org/categories/plugins/&#34;&gt;Vimcasts has a bunch of plugin related episodes&lt;/a&gt;, many of which touch on some of the plugins mentioned in this article&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Plugins are great, but only have real value if you understand how Vim can make you productive.  If you haven&amp;rsquo;t seen them yet, consider checking out the &lt;a href=&#34;http://benmccormick.org/tag/learning-vim-in-2014/&#34;&gt;other posts&lt;/a&gt; in this series to learn how Vim works before loading up on plugins.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Learning Vim in 2014: Vim as Art</title>
      <link>https://benmccormick.org/2014/07/16/054100.html</link>
      <pubDate>Wed, 16 Jul 2014 06:41:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2014/07/16/054100.html</guid>
      <description>&lt;p&gt;How do you feel about being efficient?  If you&amp;rsquo;re reading this blog, I bet you like it.  What if I told you your text editor could help you cut the amount of time you spend typing in half, with just a little reading and a bit of practice?  For you Vim users, it&amp;rsquo;s very possible that you&amp;rsquo;re spending way more time typing than needed.&lt;/p&gt;
&lt;p&gt;The software developers reading this have probably heard of the &lt;em&gt;Don&amp;rsquo;t Repeat Yourself&lt;/em&gt; principle.  Developers want to avoid duplicating work, and try to write each distinct meaningful chunk of code only once.  DRY is extremely powerful when it comes to code, but it&amp;rsquo;s also a very useful principle in text editing.  Much of the editing work we do is extremely repetitive. Vim can help you remove those inefficiencies.&lt;/p&gt;
&lt;p&gt;If Vim&amp;rsquo;s composable commands are the &lt;a href=&#34;http://benmccormick.org/2014/07/02/learning-vim-in-2014-vim-as-language/&#34;&gt;language of Vim&lt;/a&gt;, then repeating commands are it&amp;rsquo;s art.  For pretty much any thing you do in Vim, there are ways to automate and repeat it.  These &amp;ldquo;repeating commands&amp;rdquo; are powerful tools, but it&amp;rsquo;s not always easy to know what to do with them.  There aren&amp;rsquo;t simple rules you can learn for when to use repeating commands.  Instead it takes practice, awareness, and experience.&lt;/p&gt;
&lt;p&gt;All of Vim&amp;rsquo;s commands are designed to be repeatable and undoable.  So if you find yourself typing something a lot, there is likely to be a good solution for making it easier and faster.  I&amp;rsquo;m going to lay out the tools for doing that, along with a few hints for knowing when to use them.&lt;/p&gt;
&lt;h4 id=&#34;repetition-basics-the-dot-command&#34;&gt;Repetition Basics: The dot command&lt;/h4&gt;
&lt;p&gt;The most important Vim tool for repetition is the dot command.  Pressing &lt;code&gt;.&lt;/code&gt; at any time will repeat the last native command you used in Vim.  How is this useful?  Let&amp;rsquo;s say we&amp;rsquo;re faced with the following code&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; widget &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; Widget();
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; widgets &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; WidgetCollection();
widgets.push(widget);
&lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt;(widget.test()) {
    sendMessage(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;widget passed test&amp;#39;&lt;/span&gt;);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If we want to rename the &lt;code&gt;widget&lt;/code&gt; variable to be more informative, how could we go about it? We&amp;rsquo;ll ignore &amp;ldquo;language-wise&amp;rdquo; refactoring solutions, like &lt;a href=&#34;http://ternjs.net/&#34;&gt;ternjs&lt;/a&gt;, and look at the basic Vim options.&lt;/p&gt;
&lt;p&gt;A simple find and replace causes problems.  We can&amp;rsquo;t distinguish between the widget we want and other occurences.  &lt;code&gt;:%s/widget/testWidget/g&lt;/code&gt; results in plenty of unwanted changes.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; testWidget &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; Widget();
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; testWidgets &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; WidgetCollection();
testWidgets.push(testWidget);
&lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt;(testWidget.test()) {
    sendMessage(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;testWidget passed test&amp;#39;&lt;/span&gt;);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It might be possible to find a complex regex that only hit the variables we want, but thats suddenly a lot of thought for what should be a simple change.  We could go one by one and knock out each word one by one.  But that would be a lot of repeated typing of &lt;code&gt;testWidget&lt;/code&gt;.  So what can we do?&lt;/p&gt;
&lt;p&gt;The dot command is a nice solution.  If we start on the first occurence of &lt;code&gt;widget&lt;/code&gt;, we can use &lt;code&gt;ciw&lt;/code&gt; to replace the current word with new text.  When we&amp;rsquo;ve added our new text and exit insert mode, we&amp;rsquo;ll have a &lt;em&gt;command&lt;/em&gt;, which we can then repeat with &lt;code&gt;.&lt;/code&gt;. After that we can move to the next occurence we want to change and hit &lt;code&gt;.&lt;/code&gt; to replace it without retyping the variable name.  If we accidentally use it in the wrong place, it&amp;rsquo;s easy to undo with &lt;code&gt;u&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Of course it would still be a pain to navigate between each widget with hjkl.  Fortunately, Vim has more commands that allow us to avoid unecessary work.  If we start on one instance of &lt;code&gt;widget&lt;/code&gt;, we can use &lt;code&gt;*&lt;/code&gt; to search for all occurences of that word.  We can then use &lt;code&gt;n&lt;/code&gt; to move from occurence to occurence. If we overshoot and go too far, we can use &lt;code&gt;N&lt;/code&gt; to go backwards.  So if we start with &lt;code&gt;*&lt;/code&gt; (shift+8 in the gif below) and then use ciw to replace the word, we can then use &lt;code&gt;n&lt;/code&gt; and &lt;code&gt;.&lt;/code&gt; to clean up the other widgets in only 5 keystrokes.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;vimdotcommand.gif&#34; alt=&#34;vim gif&#34;&gt;&lt;/p&gt;
&lt;h4 id=&#34;the-vim-way&#34;&gt;The Vim Way&lt;/h4&gt;
&lt;p&gt;If you&amp;rsquo;re used to another editor, I&amp;rsquo;m guessing you&amp;rsquo;re justifiably a bit skeptical at this point.  After all, this example is something people do all the time, and many editors have tools to make it easy (multiple selections in Sublime Text and refactoring tools in language specific IDEs like Eclipse for instance).  They may take even fewer keystrokes than Vim. And they don&amp;rsquo;t require you to learn 6 separate commands to use well.  So what&amp;rsquo;s so special here?&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s have a quick refresher on the philosophy of Vim.  Like the Unix ecosystem it came from, Vim provides &lt;strong&gt;small&lt;/strong&gt;, &lt;strong&gt;composable&lt;/strong&gt; tools that you can combine to create powerful actions.  The power isn&amp;rsquo;t in a specific use case.  Instead it comes from the range of possibilities that open up when we start mixing and matching the code.  As with verbs, movements, and text objects, repeating commands and their corresponding reverse commands are tools we can add to our toolbox.  Using the commands above and some of the other composable commands from my &lt;a href=&#34;http://benmccormick.org/2014/07/02/learning-vim-in-2014-vim-as-language/&#34;&gt;language post&lt;/a&gt;, we can do some cool things.&lt;/p&gt;
&lt;p&gt;We can:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Search through json files and selectively remove lines that contain an attribute we don&amp;rsquo;t want to use (start on the attribute, &lt;code&gt;*&lt;/code&gt;,&lt;code&gt;dd&lt;/code&gt;, then use &lt;code&gt;n&lt;/code&gt; and &lt;code&gt;.&lt;/code&gt; repeatedly to select lines to delete)&lt;/li&gt;
&lt;li&gt;Replace a long, hard to type function name throughout the document with another version without having to type out the function name (start on the function name, &lt;code&gt;*&lt;/code&gt;,&lt;code&gt;:%s//&amp;lt;newname&amp;gt;/g&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Fix poorly indented lines using the &lt;code&gt;.&lt;/code&gt; command (&lt;code&gt;&amp;gt;&amp;gt;&lt;/code&gt; or &lt;code&gt;&amp;lt;&amp;lt;&lt;/code&gt;, &lt;code&gt;.&lt;/code&gt; repeatedly, &lt;code&gt;u&lt;/code&gt; to undo if you go too far. This can easily be used on groups of lines using visual mode too)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;What do all of these have in common?  They all use a command once, and a movement at most once, then allow for as much repetition as you like.  In &lt;a href=&#34;http://www.amazon.com/gp/product/1934356980/ref=as_li_tl?ie=UTF8&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=1934356980&amp;amp;linkCode=as2&amp;amp;tag=benmccormicko-20&amp;amp;linkId=FE3JFKHYVRYCUOVS&#34;&gt;Practical Vim&lt;/a&gt;, Drew Neil encourages actively thinking about making your actions repeatable.  In many scenarios, once you&amp;rsquo;ve made a change and movement once, you can then get by with a single keystroke for each future action and movement, with another keystroke available to cancel an action if you go too far.  Here&amp;rsquo;s a partial list of repeating commands, with the corresponding cancel command to undo them.&lt;/p&gt;
&lt;table&gt;
&lt;tr&gt;&lt;th&gt;Repeating Command&lt;/th&gt;&lt;th&gt;Purpose&lt;/th&gt;&lt;th&gt;Canceling Command&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;.&lt;/td&gt;&lt;td&gt;Repeat the last normal mode command&lt;/td&gt;&lt;td&gt;u&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;n&lt;/td&gt;&lt;td&gt;Repeat the last Search&lt;/td&gt;&lt;td&gt;N&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;;&lt;/td&gt;&lt;td&gt;Repeat the last character-wise search&lt;/td&gt;&lt;td&gt;,&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;/&lt;replacement&gt;/&lt;/td&gt;&lt;td&gt;Repeat the last search&lt;/td&gt;&lt;td&gt;N/A&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;@:&lt;/td&gt;&lt;td&gt;Repeat the last ex-mode command&lt;/td&gt;&lt;td&gt;N/A&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;@@&lt;/td&gt;&lt;td&gt;Repeat the last Macro used&lt;/td&gt;&lt;td&gt;u&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;None of these commands are all that useful on their own, but they&amp;rsquo;re each valuable things to learn as you build up your Vim toolbox. Focus on one or two to start, and learn to make edits so that you can easily repeat them. The art of Vim is learning to look for those opportunities, and crafting your commands so that they&amp;rsquo;re short, powerful, and repeatable.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&#34;more-resources&#34;&gt;More Resources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Some of you are probably confused that I wrote a whole post on repeating commands in Vim with only one side-reference to Macros.  Macros are Vim&amp;rsquo;s DRY power tool, and different enough from the rest of these commands that I didn&amp;rsquo;t want to lump it all together.  But for those interested, Drew Neil has a &lt;a href=&#34;http://vimcasts.org/episodes/converting-markdown-to-structured-html-with-a-macro/&#34;&gt;great screencast&lt;/a&gt; on how to build a good Vim macro.&lt;/li&gt;
&lt;li&gt;On a similar note, Drew&amp;rsquo;s book &lt;a href=&#34;http://www.amazon.com/gp/product/1934356980/ref=as_li_tl?ie=UTF8&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=1934356980&amp;amp;linkCode=as2&amp;amp;tag=benmccormicko-20&amp;amp;linkId=FE3JFKHYVRYCUOVS&#34;&gt;Practical Vim&lt;/a&gt; is the best guide I&amp;rsquo;ve found on making good use of repetition in Vim.  I learned plenty of the stuff in this article from that book.  For those who don&amp;rsquo;t want to pay, I&amp;rsquo;m currently giving &lt;a href=&#34;http://benmccormick.org/2014/07/11/new-twitter-feed-and-practical-vim-giveaway/&#34;&gt;new subscribers a chance to win 2 copies of the book&lt;/a&gt;.  You can also see more about repetition from Drew online at &lt;a href=&#34;http://vimcasts.org/categories/repetition/&#34;&gt;Vimcasts&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Tim Pope has published a plugin that allows you to extend the dot command to work on arbitrary user commands.  It also works out of the box with many of his other plugins.  You can see it on &lt;a href=&#34;https://github.com/tpope/vim-repeat&#34;&gt;Github&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Learning Vim in 2014: Configuring Vim</title>
      <link>https://benmccormick.org/2014/07/14/055000.html</link>
      <pubDate>Mon, 14 Jul 2014 06:50:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2014/07/14/055000.html</guid>
      <description>&lt;p&gt;Plenty of Vim articles you&amp;rsquo;ll find online start you off in the wrong place. Instead of teaching you how Vim works, they toss a bunch of scary looking code at you, tell you to shove it in a file, and claim that it will make Vim just like Textmate / Sublime / Emacs / Visual Studio. Except way cooler!  People quickly find out that if what they want is to use their old editor, they should just &lt;em&gt;use their old editor&lt;/em&gt;, and learn to use it as efficiently as possible.&lt;/p&gt;
&lt;p&gt;While writing about Vim the last few weeks, I&amp;rsquo;ve avoided recommending any configuration changes, other than the quick &lt;a href=&#34;https://gist.github.com/benmccormick/4e4bc44d8135cfc43fc3&#34;&gt;sanity vimrc&lt;/a&gt; I recommended in the first article, because I think it&amp;rsquo;s important to learn what sets Vim apart before trying to configure it.  Not because it&amp;rsquo;s good enough without configuration (honestly it&amp;rsquo;s not), but because once you understand the core, you can use configuration to build a great version of Vim instead of trying to hack together a Rube-Goldberg Textmate clone. But now that I&amp;rsquo;ve covered some of the basics (and if you haven&amp;rsquo;t yet, feel free to go ahead and start at &lt;a href=&#34;http://benmccormick.org/2014/06/30/learning-vim-in-2014-the-basics/&#34;&gt;the beginning&lt;/a&gt;), it&amp;rsquo;s time to look at Vim configuration.&lt;/p&gt;
&lt;h3 id=&#34;basic-configuration&#34;&gt;Basic Configuration&lt;/h3&gt;
&lt;p&gt;Configuration for Vim starts with a vimrc file. It&amp;rsquo;s a text file located by default at &lt;code&gt;~/.vimrc&lt;/code&gt; on *nix systems, and &lt;code&gt; $VIM\_vimrc&lt;/code&gt; on Windows.  To begin configuration you need to open that file, creating it if it doesn&amp;rsquo;t exist. But before we go further, we should stop and figure out what we&amp;rsquo;re doing.&lt;/p&gt;
&lt;p&gt;I said that configuration starts with the vimrc file, but the truth is that your vimrc is just a normal text file that Vim sources by default.  The heart of Vim configuration is Vimscript, Vim&amp;rsquo;s custom scripting language.  Vimscript is a full programming language, with variables and control structures.  But for this article we&amp;rsquo;re going to focus on using it for configuration.&lt;/p&gt;
&lt;p&gt;The basic commands that Vimscript uses for configuration are &lt;code&gt;let&lt;/code&gt;, &lt;code&gt;set&lt;/code&gt;, and &lt;code&gt;map&lt;/code&gt;. &lt;code&gt;let&lt;/code&gt; allows you to change a variable value with the syntax &lt;code&gt;let &amp;lt;var-name&amp;gt;=&amp;lt;value&amp;gt;&lt;/code&gt;. &lt;code&gt;set&lt;/code&gt; allows you to read or change an option value using &lt;code&gt;set &amp;lt;option-name&amp;gt;&lt;/code&gt; for toggle options or &lt;code&gt;set &amp;lt;option-name&amp;gt;=&amp;lt;option-value&amp;gt;&lt;/code&gt; for numeric or string-based options. &lt;code&gt;map&lt;/code&gt; and its many variations allow you to create new keymappings by setting the output of one key combination to produce the value of another key combination.  You can use variations on map to specify how a key sequence should behave in different vim modes.&lt;/p&gt;
&lt;h3 id=&#34;know-what-youre-configuring&#34;&gt;Know what you&amp;rsquo;re configuring&lt;/h3&gt;
&lt;p&gt;Now that you know the basic commands, I could show you an example .vimrc, explain it a bit and then tell you to copy it, change the stuff you don&amp;rsquo;t like, and go on your way.  The problem with that? It leaves your vimrc file as a &amp;ldquo;pile of junk&amp;rdquo;, that I understand and you don&amp;rsquo;t.   If I did a good job, you might understand the purpose of individual lines, but they probably wouldn&amp;rsquo;t be the best fit for you, and you probably wouldn&amp;rsquo;t know exactly how to make it better.  In the end you&amp;rsquo;ll keep tossing junk onto it until it becomes a confusing mess you want to avoid.  So instead, I&amp;rsquo;m going to walk through the types of configurations you might want to consider, give a few examples, and let you build from there.  So here are a few concepts to think about as you construct your vimrc file:&lt;/p&gt;
&lt;h4 id=&#34;adapt-to-your-environment&#34;&gt;Adapt to your environment&lt;/h4&gt;
&lt;p&gt;Vi and Vim were originally developed in a low-resource terminal based environment.  Many of their default settings and assumptions reflect that.  Today though Vim is used in a wide variety of ways, from multimonitor Mac Pros with 16+GB of memory running multiple MacVim windows, to low memory remote servers running Vim in the terminal over ssh.  If you know what your environment will look like, you can optimize Vim for your own use.&lt;/p&gt;
&lt;p&gt;For instance, if you&amp;rsquo;re running in a high resource environment, (and pretty much any modern laptop or desktop these days qualifies as a high resource environment) you may want to enable some features that Vim disables by default, since those removing those features allow it to work well in very low memory situations.  Some  common choices:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-vimscript&#34; data-lang=&#34;vimscript&#34;&gt;syntax enable &amp;quot; Turn on syntax highlighting
set hidden &amp;quot; Leave hidden buffers open
set history=100 &amp;quot;by default Vim saves your last 8 commands.  We can handle more
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;On the other hand, if you know you&amp;rsquo;re going to be running remotely on low resource machines, you might choose to disable those options to minimize the load and increase speed. I&amp;rsquo;ll talk more about plugins in a later post, but they&amp;rsquo;re another thing that works much better in your local environment than on remote servers, for both performance and logistical reasons.&lt;/p&gt;
&lt;h4 id=&#34;add-some-visual-niceties&#34;&gt;Add some visual niceties&lt;/h4&gt;
&lt;p&gt;If we&amp;rsquo;re honest, I think most people can agree Vim is pretty hard to look at out of the box.  Very few visual affordances, no syntax highlighting or line numbers, and it&amp;rsquo;s style is dependent on your terminal color scheme or an ugly default gVim theme. But that&amp;rsquo;s pretty easy to fix. We can get syntax highlighting and line numbers with this snippet:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-vimscript&#34; data-lang=&#34;vimscript&#34;&gt;syntax enable
set number
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Getting a decent color scheme will require you to download it as a plugin, but if you&amp;rsquo;ve done that or if you like one of the colorschemes that ship with your Vim distribution it&amp;rsquo;s easy to set up with &lt;code&gt;colorscheme &amp;lt;theme-name&amp;gt;&lt;/code&gt;.  Beyond that, there&amp;rsquo;s plenty more you can do to improve the visual feel of Vim.  I&amp;rsquo;d look into customizing your status bar, relative vs absolute line numbers, and plugins like &lt;a href=&#34;https://github.com/bling/vim-airline&#34;&gt;Airline&lt;/a&gt; and &lt;a href=&#34;https://github.com/reedes/vim-thematic&#34;&gt;Vim-Thematic&lt;/a&gt;.&lt;/p&gt;
&lt;h4 id=&#34;set-up-keybindings&#34;&gt;Set up keybindings&lt;/h4&gt;
&lt;p&gt;Many of Vim&amp;rsquo;s useful commands are either not given default keybindings, or are given hard to remember obtuse ones.  Don&amp;rsquo;t want to spend your whole life typing &lt;code&gt;source ~/.vimrc&lt;/code&gt; into each file everytime you add something to your configuration? I shortcut that to &lt;code&gt;\rr&lt;/code&gt;.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-vimscript&#34; data-lang=&#34;vimscript&#34;&gt;map &amp;lt;leader&amp;gt;rr :source ~/.vimrc&amp;lt;CR&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You might be wondering what the &lt;leader&gt; notation is there.  The &lt;code&gt;&amp;lt;leader&amp;gt;&lt;/code&gt; key is a Vim convention for a key that comes before user created keystrokes.  It&amp;rsquo;s meant to minimize conflicts, and allow plugins to provide default mappings while still allowing the user a bit of flexibility.  The leader key can be set in your vimrc with the command &lt;code&gt;let mapleader=&amp;lt;yourleaderkey&amp;gt;&lt;/code&gt;.  The default is &lt;code&gt;\&lt;/code&gt;, and I would recommend leaving it that way to start.  You can change it later if you find it to be inconvenient, and it doesn&amp;rsquo;t cause any conflicts since its the default key.  Common replacements like &lt;code&gt;,&lt;/code&gt; overwrite useful functionality that may not be immediately obvious (&lt;code&gt;,&lt;/code&gt; allows you to move backwards on a characterwise search for instance).&lt;/p&gt;
&lt;h4 id=&#34;configure-plugins-and-file-type-specific-settings&#34;&gt;Configure plugins and file-type specific settings&lt;/h4&gt;
&lt;p&gt;I&amp;rsquo;ll touch more on plugins in a future post, but many of them allow extensive configuration, including setting keybindings, changing default behaviors, and enabling/disabling extra functionality. All of that happens here in the vimrc and should mostly use the let/set/map commands that we&amp;rsquo;ve already seen.&lt;/p&gt;
&lt;p&gt;You can also set file-type specific rules.  Rather than placing these in your main vimrc, these go into a special &amp;ldquo;file type plugins&amp;rdquo; directory, &lt;code&gt;~/.vim/ftplugin&lt;/code&gt;.  Within that directory, you can create files like javascript.vim, python.vim or html.vim, and those files will be loaded after the vimrc when you open files of that type. Using those files, you can create completely separate profiles for each file type.&lt;/p&gt;
&lt;h3 id=&#34;discover-whats-out-there&#34;&gt;Discover what&amp;rsquo;s out there&lt;/h3&gt;
&lt;p&gt;I&amp;rsquo;ve intentionally avoided telling you what your vimrc should look like here.  I&amp;rsquo;ve tried to show you the big picture of what you can do, and now I&amp;rsquo;ll leave it to you to figure out what pieces you need to be comfortable and productive.  It will be different for everybody.&lt;/p&gt;
&lt;p&gt;My advice?  Now that you know what you&amp;rsquo;re looking for, go and take a look at other people&amp;rsquo;s configurations. Start with something like this &lt;a href=&#34;https://github.com/benmccormick/dotfiles/blob/master/vim/vimrc.symlink&#34;&gt;vimrc boilerplate&lt;/a&gt;, and add the things you like.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s pretty easy to find good configurations online if you look.  &lt;a href=&#34;https://github.com/ben336/dotfiles/blob/master/vim/vimrc.symlink&#34;&gt;My vimrc file&lt;/a&gt; is on Github.  It&amp;rsquo;s certainly not the best out there, but its relatively small and easy to follow.  If you know developers you admire who use Vim, ask to see their vimrc files, or see if they have any fancy tricks to share.  For those without those resources,  Github&amp;rsquo;s &lt;a href=&#34;http://dotfiles.github.io/&#34;&gt;dotfile page&lt;/a&gt; is a great place to look.  It contains links to several very detailed &amp;ldquo;dotfile repos&amp;rdquo; from various developers. You don&amp;rsquo;t have to copy everything from these files (in fact you shouldn&amp;rsquo;t), but you can pull the things that look useful, get rid of things that don&amp;rsquo;t, and try things out as you slowly build up your own workspace, built to do the jobs that you need it to do.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&#34;more-resources&#34;&gt;More Resources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://dotfiles.github.io/&#34;&gt;Github&amp;rsquo;s dotfile page&lt;/a&gt; provides some great pointers to dotfile repositories from experienced developers that can help you come up with cool configuration ideas&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/carlhuda/janus&#34;&gt;Janus&lt;/a&gt; is a great resource for users who&amp;rsquo;d prefer to avoid configuration and just start with a useable editor.  Though if that&amp;rsquo;s you, you may find you&amp;rsquo;re better off &lt;a href=&#34;http://delvarworld.github.io/blog/2013/03/16/just-use-sublime-text/&#34;&gt;just using Sublime Text&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
</description>
    </item>
    
    <item>
      <title>New Twitter Feed and Practical Vim Giveaway</title>
      <link>https://benmccormick.org/2014/07/11/061200.html</link>
      <pubDate>Fri, 11 Jul 2014 07:12:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2014/07/11/061200.html</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve got a few orders of site business to deal with today.  First, there&amp;rsquo;s a new way to subscribe to the site.&lt;/p&gt;
&lt;h3 id=&#34;new-twitter-feed&#34;&gt;New Twitter Feed&lt;/h3&gt;
&lt;p&gt;The new feed, &lt;a href=&#34;http://twitter.com/benmccormickorg&#34;&gt;@benmccormickorg&lt;/a&gt;, will be a Twitter &amp;ldquo;RSS Feed&amp;rdquo; with all of the posts from this site. It&amp;rsquo;s just another option for people who want to subscribe, along with &lt;a href=&#34;http://feedpress.me/benmccormick&#34;&gt;RSS&lt;/a&gt; and my &lt;a href=&#34;http://eepurl.com/WFYon&#34;&gt;mailing list&lt;/a&gt;.  You can also find my personal account at &lt;a href=&#34;http://twitter.com/_benmccormick&#34;&gt;@_benmccormick&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://twitter.com/benmccormickorg&#34; class=&#34;twitter-follow-button&#34; data-show-count=&#34;false&#34; data-lang=&#34;en&#34;&gt;Follow @benmccormickorg&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;practical-vim-giveaway&#34;&gt;Practical Vim Giveaway&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;vim.jpg&#34; alt=&#34;Practical Vim&#34;&gt;&lt;/p&gt;
&lt;p&gt;To go along with that, and as a thanks for all of the great interest and feedback I&amp;rsquo;ve gotten for my posts on Vim recently, I&amp;rsquo;m going to be giving away 2 copies of Drew Neil&amp;rsquo;s book, Practical Vim.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://www.amazon.com/gp/product/1934356980/ref=as_li_tl?ie=UTF8&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=1934356980&amp;amp;linkCode=as2&amp;amp;tag=benmccormicko-20&amp;amp;linkId=FE3JFKHYVRYCUOVS&#34;&gt;Practical Vim&lt;/a&gt; is the best resource on Vim I&amp;rsquo;ve found.  Drew Neil is the creator of &lt;a href=&#34;http://vimcasts.org/&#34;&gt;vimcasts&lt;/a&gt;, the popular online Vim site.  And this book is his attempt to explain what makes Vim special.  It&amp;rsquo;s bursting cover to cover with practical tips and tricks to help you become a more efficient writer and developer.  Reading it helped me understand the philosophy behind Vim, and I would recommend it for anyone who uses Vim or thinks they might want to.  There&amp;rsquo;s a reason I recommend it as the Vim resource on my &lt;a href=&#34;http://benmccormick.org/readinglist/&#34;&gt;reading list&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So how do you get a copy?  There are a few ways&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Follow &lt;a href=&#34;http://twitter.com/benmccormickorg&#34;&gt;@benmccormickorg&lt;/a&gt; on Twitter&lt;/li&gt;
&lt;li&gt;Subscribe to my &lt;a href=&#34;http://eepurl.com/WFYon&#34;&gt;mailing list feed&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Tweet a link to one of my &lt;em&gt;Learning Vim&lt;/em&gt; posts, with the hashtag &lt;strong&gt;#learningvim&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You can accumulate up to 3 entries by doing each of the above (I won&amp;rsquo;t count multiple tweets for the 3rd).  The giveaway will end July 25th, at which time I&amp;rsquo;ll pick 2 winners at random, and get in touch through Twitter or email.  If you have questions or concerns, feel free to speak up in the comments. Otherwise, go subscribe and win a chance to get a great book for free!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Book Review: Building Backbone Plugins</title>
      <link>https://benmccormick.org/2014/07/09/063840.html</link>
      <pubDate>Wed, 09 Jul 2014 07:38:40 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2014/07/09/063840.html</guid>
      <description>&lt;p&gt;As the saying goes, judging a book by its cover is a dangerous business.  A lot of books have titles that promise great things, and content that under-delivers and disappoints.  Every once in a while, though, you find a gem that does the opposite. &lt;a href=&#34;https://leanpub.com/building-backbone-plugins?a=3a4Srv2pP9p87WQ_eoDoGp&#34;&gt;Building Backbone Plugins&lt;/a&gt; sounds like a niche book for library developers.  But it actually is the best resource on &lt;a href=&#34;http://backbonejs.org/&#34;&gt;Backbone.JS&lt;/a&gt; development I&amp;rsquo;ve found, a book that will benefit anyone who works with Backbone.&lt;/p&gt;
&lt;p&gt;So what&amp;rsquo;s the fuss about?  The book&amp;rsquo;s author, Derick Bailey, is the creator of &lt;a href=&#34;http://marionettejs.com/&#34;&gt;Marionette.JS&lt;/a&gt;, a popular application framework for Backbone Apps.  &lt;em&gt;Building Backbone Plugins&lt;/em&gt; explores the problems that Derick tried to solve with Marionette and then explains the mindset behind Marionette&amp;rsquo;s solutions.  It is not a book exclusively about Marionette though.  The solutions in the book are example code that represents a simplified view of what Marionette does.  Instead the book looks at the common problems any developer will encounter in a Backbone project, and provides a possible solution, while working hard to generalize the lessons and concepts as much as possible.&lt;/p&gt;
&lt;p&gt;Building Backbone Plugins is divided into 4 parts.  The first two look at Backbone Views and dealing with the DOM.  The third looks at Models and Collections.  The last part deals with application structure and events.  These are followed by a series of appendices that read as stretched-out blog posts on a variety of related topics that didn&amp;rsquo;t quite fit into one of the 4 buckets that the rest of the book falls into.&lt;/p&gt;
&lt;p&gt;In my mind, the first two parts are the heart of the book.  They&amp;rsquo;re a step-by-step look at how you can remove repetitive code from your Backbone Views and structure your application to expose the developers intent in each file, rather than burying the purpose in boilerplate. I learned a lot about how I could improve my Backbone code, and these two sections actually inspired me to start integrating Marionette into a project at work. The application structure advice in the fourth part is also particularly strong, with quality information about events, and ideas on how to scale a Backbone application beyond TodoMVC sizes.&lt;/p&gt;
&lt;p&gt;On the other hand, the appendices feel a bit tacked on, and seem to be full of stuff the author wanted to add but couldn&amp;rsquo;t figure out how to weave into the rest of the book.  Since it&amp;rsquo;s legitimate content rather than simply greater detail on things that have been already covered, they don&amp;rsquo;t act as real appendices and leave the book feeling a bit unfocused at the end. When you combine that with some weaker content in part 3 (where the author moves away from Marionette into some other smaller examples), the book can feel a bit choppy and directionless.  But the goldmine of knowledge and perspective in Parts 1, 2 and 4 more than make up for it.&lt;/p&gt;
&lt;p&gt;I would not recommend BBP as a &amp;ldquo;first book&amp;rdquo; on Backbone.  It assumes plenty of knowledge, and doesn&amp;rsquo;t attempt to teach Backbone basics.  But for an intermediate level Backbone developer, or any Javascript developer who wants to grow their thinking about application structure, there is plenty of solid insight here. Meditations on handling nested views, cleaning up unused views, abstracting out repetitive boilerplate, and structuring genuinely large applications are all worth the price of the book.  Finally, if you&amp;rsquo;re writing code using Marionette already, this book is a must-have.  Marionette&amp;rsquo;s documentation does a great job of explaining the &amp;ldquo;what&amp;rdquo; and the &amp;ldquo;how&amp;rdquo; of Marionette.  But this book explains the all-important &amp;ldquo;why&amp;rdquo; of a framework that is based on encoding Backbone best practices into a library. It will help you think like an experienced Backbone developer.&lt;/p&gt;
&lt;h3 id=&#34;more-resources&#34;&gt;More Resources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://leanpub.com/building-backbone-plugins?a=3a4Srv2pP9p87WQ_eoDoGp&#34;&gt;Building Backbone Plugins&lt;/a&gt; - You can purchase the book on leanpub. (Note: Affiliate Link)&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://addyosmani.github.io/backbone-fundamentals/&#34;&gt;Developing Backbone Applications&lt;/a&gt; - This book by Addy Osmani is a great resource for Backbone Beginners who want a more basic introduction to Backbone concepts.  It&amp;rsquo;s available as a free HTMl site on github, but you also can &lt;a href=&#34;http://www.amazon.com/gp/product/1449328253/ref=as_li_tl?ie=UTF8&amp;camp=1789&amp;creative=390957&amp;creativeASIN=1449328253&amp;linkCode=as2&amp;tag=productjavasc-20&amp;linkId=5RQTSOTPFIGKMLJK&#34;&gt;purchase it as a paperback or ebook.&lt;/a&gt;&lt;img src=&#34;http://ir-na.amazon-adsystem.com/e/ir?t=productjavasc-20&amp;l=as2&amp;o=1&amp;a=1449328253&#34; width=&#34;1&#34; height=&#34;1&#34; alt=&#34;&#34; style=&#34;border:none !important; margin:0px !important;&#34; /&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://marionettejs.com/&#34;&gt;Marionette.js&lt;/a&gt; - This framework serves as the inspiration for Derick&amp;rsquo;s book and is a great way to structure larger Backbone apps.&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Learning Vim in 2014: Working with Files</title>
      <link>https://benmccormick.org/2014/07/07/061037.html</link>
      <pubDate>Mon, 07 Jul 2014 07:10:37 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2014/07/07/061037.html</guid>
      <description>&lt;p&gt;As a software developer, you shouldn&amp;rsquo;t have to spend time thinking about how to get to the code you want to edit.  One of the messiest parts of my transition to using Vim full time was its way of dealing with files.  Coming to Vim after primarily using Eclipse and Sublime Text, it frustrated me that Vim doesn&amp;rsquo;t bundle a persistent file system viewer, and the built-in ways of opening and switching files always felt extremely painful.&lt;/p&gt;
&lt;p&gt;At this point I appreciate the depth of Vim&amp;rsquo;s file management features. I&amp;rsquo;ve put together a system that works for me even better than more visual editors once did. Because it&amp;rsquo;s purely keyboard based, it allows me to move through my code much faster.  That took some time though, and involves several plugins. But the first step was me understanding Vim&amp;rsquo;s built in options for dealing with files. This post will be looking at the most important structures Vim provides you for file management, with a quick peek at some of the more advanced features you can get through plugins.&lt;/p&gt;
&lt;h3 id=&#34;the-basics-opening-a-new-file&#34;&gt;The Basics: Opening a new file&lt;/h3&gt;
&lt;p&gt;One of the biggest obstacles to learning Vim is its lack of visual affordances.  Unlike modern GUI based editors, there is no obvious way to do anything when you open a new instance of Vim in the terminal.  Everything is done through keyboard commands, and while that ends up being more efficient for experienced users, new Vim users will find themselves looking up even basic commands routinely.  So lets start with the basics.&lt;/p&gt;
&lt;p&gt;The command to open a new file in Vim is &lt;code&gt;:e &amp;lt;filename&amp;gt;&lt;/code&gt;.  &lt;code&gt;:e&lt;/code&gt; opens up a new buffer with the contents of the file inside. If the file doesn&amp;rsquo;t exist yet it opens up an empty buffer and will write to the file location you specify once you make changes and save. Buffers are Vim&amp;rsquo;s term for a &amp;ldquo;block of text stored in memory&amp;rdquo;. That text can be associated with an existing file or not, but there will be one buffer for each file you have open.&lt;/p&gt;
&lt;p&gt;After you open a file and make changes, you can save the contents of the buffer back to the file with the write command &lt;code&gt;:w&lt;/code&gt;.  If the buffer is not yet associated with a file or you want to save to a different location, you can save to a specific file with &lt;code&gt;:w &amp;lt;filename&amp;gt;&lt;/code&gt;. You may need to add a &lt;code&gt;!&lt;/code&gt; and use &lt;code&gt;:w! &amp;lt;filename&amp;gt;&lt;/code&gt; if you&amp;rsquo;re overwriting an existing file.&lt;/p&gt;
&lt;p&gt;This is the survival level knowledge for dealing with Vim files.  Plenty of developers get by with just these commands, and its technically all you need.  But Vim offers a lot more for those who dig a bit deeper.&lt;/p&gt;
&lt;h3 id=&#34;buffer-management&#34;&gt;Buffer Management&lt;/h3&gt;
&lt;p&gt;Moving beyond the basics, let&amp;rsquo;s talk some more about buffers.  Vim handles open files a bit differently than other editors.  Rather than leaving all open files visible as tabs, or only allowing you to have one file open at a time, Vim allows you to have multiple buffers open.  Some of these may be visible while others are not.  You can view a list of all open buffers at any time with &lt;code&gt;:ls&lt;/code&gt;.  This shows each open buffer, along with their buffer number.  You can then switch to a specific buffer with the &lt;code&gt;:b &amp;lt;buffer-number&amp;gt;&lt;/code&gt; command, or move in order along the list with the &lt;code&gt;:bnext&lt;/code&gt; and &lt;code&gt;:bprevious&lt;/code&gt; commands. (these can be shortened to &lt;code&gt;:bn&lt;/code&gt; and &lt;code&gt;:bp&lt;/code&gt; respectively).&lt;/p&gt;
&lt;p&gt;While these commands are the fundamental Vim solutions for managing buffers, I&amp;rsquo;ve found that they don&amp;rsquo;t map well to my own way of thinking about files.  I don&amp;rsquo;t want to care about the order of buffers, I just want to go to the file I&amp;rsquo;m thinking about, or maybe to the file I was just in before the current one.  So while its important to understand Vim&amp;rsquo;s underlying buffer model, I wouldn&amp;rsquo;t necessarily recommend its builtin commands as your main file management strategy.  There are more powerful options available.&lt;/p&gt;
&lt;img alt=&#34;splits example&#34; class=&#34;full-width&#34; src=&#34;skitch.jpeg&#34;&gt;
&lt;h3 id=&#34;splits&#34;&gt;Splits&lt;/h3&gt;
&lt;p&gt;One of the best parts of managing files in Vim is its splits.  With Vim, you can split your current window into 2 windows at any time, and then resize and arrange them into any configuration you like.  Its not unusual for me to have 6 files open at a given time, each with its own small split of the window.&lt;/p&gt;
&lt;p&gt;You can open a new split with &lt;code&gt;:sp &amp;lt;filename&amp;gt;&lt;/code&gt; or &lt;code&gt;:vs &amp;lt;filename&amp;gt;&lt;/code&gt;, for horizontal and vertical splits respectively.  There are keyword commands you can use to then resize the windows the way you want them, but to be honest this is the one Vim task I prefer to do with my mouse.  A mouse gives me more precision without having to guess the number of columns I want or fiddle back and forth between 2 widths.&lt;/p&gt;
&lt;p&gt;After you create some splits, you can switch back and forth between them with &lt;code&gt;ctrl-w [h|j|k|l]&lt;/code&gt;.  This is a bit clunky though, and it&amp;rsquo;s important for common operations to be efficient and easy. If you use splits heavily, I would personally recommend aliasing these commands to &lt;code&gt;ctrl-h&lt;/code&gt; &lt;code&gt;ctrl-j&lt;/code&gt; etc in your .vimrc using this snippet.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-vimscript&#34; data-lang=&#34;vimscript&#34;&gt;nnoremap &amp;lt;C-J&amp;gt; &amp;lt;C-W&amp;gt;&amp;lt;C-J&amp;gt; &amp;quot;Ctrl-j to move down a split
nnoremap &amp;lt;C-K&amp;gt; &amp;lt;C-W&amp;gt;&amp;lt;C-K&amp;gt; &amp;quot;Ctrl-k to move up a split
nnoremap &amp;lt;C-L&amp;gt; &amp;lt;C-W&amp;gt;&amp;lt;C-L&amp;gt; &amp;quot;Ctrl-l to move	right a split
nnoremap &amp;lt;C-H&amp;gt; &amp;lt;C-W&amp;gt;&amp;lt;C-H&amp;gt; &amp;quot;Ctrl-h to move left a split
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;the-jumplist&#34;&gt;The jumplist&lt;/h3&gt;
&lt;p&gt;Splits solve the problem of viewing multiple related files at a time, but we still haven&amp;rsquo;t seen a satisfactory solution for moving quickly between open and hidden files.  The jumplist is one tool you can use for that.&lt;/p&gt;
&lt;p&gt;The jumplist is one of those Vim features that can appear weird or even useless at first.  Vim keeps track of every motion command and file switch you make as you&amp;rsquo;re editing files.  Every time you &amp;ldquo;jump&amp;rdquo; from one place to another in a split, Vim adds an entry to the jumplist. While this may initially seem like a small thing, it becomes powerful when you&amp;rsquo;re switching files a lot, or moving around in a large file.  Instead of having to remember your place, or worry about what file you were in, you can instead retrace your footsteps quickly using some quick key commands.  &lt;code&gt;Ctrl-o&lt;/code&gt; allows you to jump back to your last jump location.  Repeating it multiple times allows you to quickly jump back to the last file or code chunk you were working on, without having to keep the details of where that code is in your head. You can then move back up the chain with &lt;code&gt;ctrl-i&lt;/code&gt;. This turns out to be immensely powerful when you&amp;rsquo;re moving around in code quickly, debugging a problem in multiple files or flipping back and forth between 2 files. Instead of typing file names or remembering buffer numbers, you can just move up and down the existing path.  It&amp;rsquo;s not the answer to everything, but like other Vim concepts, it&amp;rsquo;s a small focused tool that adds to the overall power of the editor without trying to do everything.&lt;/p&gt;
&lt;h3 id=&#34;plugins&#34;&gt;Plugins&lt;/h3&gt;
&lt;p&gt;So let&amp;rsquo;s be real, if you&amp;rsquo;re coming to Vim from something like Sublime Text or Atom, there&amp;rsquo;s a good chance all of this looks a bit arcane, scary, and inefficient.  &amp;ldquo;Why would I want to type the full path to open a file when Sublime has fuzzy finding?&amp;rdquo;  &amp;ldquo;How can I get a view of a project&amp;rsquo;s structure without a sidebar to show the directory tree?&amp;rdquo;  Legitimate questions.  The good news is that Vim has solutions.  They&amp;rsquo;re just not baked into the Vim core.  I&amp;rsquo;ll touch more on Vim configuration and plugins in later posts, but for now here&amp;rsquo;s a pointer to 3 helpful plugins that you can use to get Sublime-like file management.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/kien/ctrlp.vim&#34;&gt;CtrlP&lt;/a&gt; is a fuzzy finding file search similar to Sublime&amp;rsquo;s &amp;ldquo;Go to Anything&amp;rdquo; bar.  It&amp;rsquo;s lightning fast and pretty configurable.  I use it as my main way of opening new files.  With it I only need to know part of the file name and don&amp;rsquo;t need to memorize my project&amp;rsquo;s directory structure.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/scrooloose/nerdtree&#34;&gt;The NERDTree&lt;/a&gt; is a &amp;ldquo;file navigation drawer&amp;rdquo; plugin that replicates the side file navigation that many editors have.  I actually rarely use it, as fuzzy search always seems faster to me.  But it can be useful coming into a project, when you&amp;rsquo;re trying to learn the project structure and see what&amp;rsquo;s available.  NERDTree is immensely configurable, and also replaces Vim&amp;rsquo;s built in directory tools when installed.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/mileszs/ack.vim&#34;&gt;Ack.vim&lt;/a&gt; is a code search plugin for Vim that allows you to search across your project for text expressions.  It acts as a light wrapper around Ack or Ag, &lt;a href=&#34;http://benmccormick.org/2013/11/25/a-look-at-ack/&#34;&gt;2 great code search tools&lt;/a&gt;, and allows you to quickly jump to any occurrence of a search term in your project.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Between it&amp;rsquo;s core and its plugin ecosystem, Vim offers enough tools to allow you to craft your workflow anyway you want.  File management is a key part of a good software development system, and it&amp;rsquo;s worth experimenting to get it right.&lt;/p&gt;
&lt;p&gt;Start with the basics for long enough to understand them, and then start adding tools on top until you find a comfortable workflow. It will all be worth it when you&amp;rsquo;re able to seamlessly move to the code you want to work on without the mental overhead of figuring out how to get there.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&#34;more-resources&#34;&gt;More Resources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://robots.thoughtbot.com/seamlessly-navigate-vim-and-tmux-splits&#34;&gt;Seamlessly Navigate Vim &amp;amp; Tmux Splits&lt;/a&gt; - This is a must read for anyone who wants to use vim with &lt;a href=&#34;http://tmux.sourceforge.net/&#34;&gt;tmux&lt;/a&gt;.  It presents an easy system for treating Vim and Tmux splits as equals, and moving between them easily.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://vim.wikia.com/wiki/Using_tab_pages&#34;&gt;Using Tab Pages&lt;/a&gt; - One file management feature I didn&amp;rsquo;t cover, since it&amp;rsquo;s poorly named and a bit confusing to use, is Vim&amp;rsquo;s &amp;ldquo;tab&amp;rdquo; feature.  This post on the Vim wiki gives a good overview of how you can use &amp;ldquo;tab pages&amp;rdquo; to have multiple views of your current workspace&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://vimcasts.org/episodes/the-edit-command/&#34;&gt;Vimcasts: The edit command&lt;/a&gt; - Vimcasts in general is a great resource for anyone learning Vim, but this screenshot does a good job of covering the file opening basics mentioned above, with some suggestions on improving the builtin workflow&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Learning Vim in 2014: Vim as Language</title>
      <link>https://benmccormick.org/2014/07/02/062700.html</link>
      <pubDate>Wed, 02 Jul 2014 07:27:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2014/07/02/062700.html</guid>
      <description>&lt;p&gt;Wouldn&amp;rsquo;t it be nice if your text editor just did what you said instead of making you slowly and manually add and delete characters?  Vim doesn&amp;rsquo;t speak English, but it has a language of its own, built out of composable commands, that is much more efficient than the simple movement and editing commands you&amp;rsquo;ll find in other editors.  In my &lt;a href=&#34;http://benmccormick.org/2014/06/30/learning-vim-in-2014-the-basics/&#34;&gt;last post&lt;/a&gt;, I took an initial look at Vim as a language.  I&amp;rsquo;m going to dive deeper into that here.&lt;/p&gt;
&lt;h3 id=&#34;vim-verbs-what-can-you-do&#34;&gt;Vim Verbs: What can you do?&lt;/h3&gt;
&lt;p&gt;Vim&amp;rsquo;s &amp;ldquo;verbs&amp;rdquo; mostly fall into 2 main categories.  Some of them act on a single character, and others act on a &amp;ldquo;motion&amp;rdquo; or &amp;ldquo;text object&amp;rdquo;.  We&amp;rsquo;ll look at motions in a second, but lets start by looking at the verbs.&lt;/p&gt;
&lt;h4 id=&#34;single-character-verbs&#34;&gt;Single character verbs&lt;/h4&gt;
&lt;p&gt;So like I said, there are a few vim actions that act on a single character.  They act as shortcuts for actions that you can also perform with motions, and allow you to save a few keystrokes.&lt;/p&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;td&gt;Delete character under the cursor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;r&lt;/td&gt;&lt;td&gt;Replace character under cursor with another character&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;s&lt;/td&gt;&lt;td&gt;Delete character under cursor and move to insert mode&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;These are great commands to know, and things that I use daily, but they act as a bit of an island.  Let&amp;rsquo;s look at some verbs with more power.&lt;/p&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;d&lt;motion&gt;&lt;/td&gt;&lt;td&gt;Delete text specified by motion&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;c&lt;motion&gt;&lt;/td&gt;&lt;td&gt;Delete text specified by motion and go into insert mode&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;y&lt;motion&gt;&lt;/td&gt;&lt;td&gt;Yank (copy) text specified by motion&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;These aren&amp;rsquo;t the only 3 actions that you can use with motions, but they&amp;rsquo;re probably the most important. The first 2 are roughly the same as deleting or cutting in most instances, with the option to choose what mode you end in. The 3rd is Vim&amp;rsquo;s version of copying.&lt;/p&gt;
&lt;h4 id=&#34;motions&#34;&gt;Motions&lt;/h4&gt;
&lt;p&gt;So how do we use these actions?  You&amp;rsquo;ll notice that if you type any of the above characters into Vim by themselves, nothing happens.  That&amp;rsquo;s because they&amp;rsquo;re expecting something to act on.  If you&amp;rsquo;re a grammar nerd or remember your 8th grade english classes, you can think of these as transitive verbs that need to act on a direct object.  These &amp;ldquo;direct objects&amp;rdquo; come in 2 forms, motions and text objects.  Motions are the motion commands that you can use at any time to move around Vim.  Some examples:&lt;/p&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Motion&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$&lt;motion&gt;&lt;/td&gt;&lt;td&gt;Go to the end of the line&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;G&lt;motion&gt;&lt;/td&gt;&lt;td&gt;Go to the end of the file&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;f.&lt;motion&gt;&lt;/td&gt;&lt;td&gt;Go to the next occurrence of `.` on the current line&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;All of these commands work as motions on their own, but when you combine them with actions you can get powerful effects.  So &lt;code&gt;d$&lt;/code&gt; means &amp;ldquo;delete to the end of the line&amp;rdquo;.  &lt;code&gt;cf)&lt;/code&gt; means &amp;ldquo;change through the next closing parentheses&amp;rdquo; and &lt;code&gt;yG&lt;/code&gt; means copy everything through the end of the file.  The list above is only a small subset of the motions available.  I&amp;rsquo;d suggest learning 1 or 2 to start and using them when appropriate.  As you get more comfortable with Vim you can continue to add more, and each one will unlock a set of commands for all of the actions you know.&lt;/p&gt;
&lt;p&gt;The second type of &amp;ldquo;direct object&amp;rdquo; that Vim verbs can take is a text object.  You can think of text objects as a &amp;ldquo;defined chunk of text.&amp;rdquo;  Some examples include selecting words, html tag contents, or the contents of a function.&lt;/p&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Text Object&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;iw&lt;/td&gt;&lt;td&gt;Applies to everything in the current word&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;it&lt;motion&gt;&lt;/td&gt;&lt;td&gt;Applies to everything in current xml/html tag&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;i{&lt;motion&gt;&lt;/td&gt;&lt;td&gt;Applies to everything inside nearest curly brackets&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;So using text objects you can change the contents of a word with the easily memorizable &lt;code&gt;ciw&lt;/code&gt; (change in word), or copy the contents of an html &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; tag with yit.  It&amp;rsquo;s worth mentioning here that one of the most powerful text objects is a bit of an oddball.  A really common thing people do is applying an action to the current line.  Vi&amp;rsquo;s language makes this easy by allowing the shortcut for this text object to be a simple repeat of the action.  So &lt;code&gt;yy&lt;/code&gt; yanks the current line, &lt;code&gt;dd&lt;/code&gt; deletes it, and &lt;code&gt;cc&lt;/code&gt; changes it.&lt;/p&gt;
&lt;h4 id=&#34;piece-by-piece&#34;&gt;Piece by Piece&lt;/h4&gt;
&lt;p&gt;The key here is that learning Vim isn&amp;rsquo;t something you do in a weekend. It&amp;rsquo;s an iterative process. Since the actions, motions, and text objects build on themselves, you can start to grow your toolbox exponentially as time goes on.  But you&amp;rsquo;ll want to start with a few commands that you find make you productive.  I&amp;rsquo;ve personally found &lt;code&gt;ciw&lt;/code&gt;, &lt;code&gt;dd&lt;/code&gt; and &lt;code&gt;ci(&lt;/code&gt; to be incredibly useful commands, and a great place to start as you learn to use these commands instead of the slower &amp;ldquo;mouse and select&amp;rdquo; methods that you may be used to. When we learn languages we all start with basic sentences, learn the grammar rules and grow from there.  Vim is no different. Start small and add to your toolbox as you build great things with it.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&#34;more-resources&#34;&gt;More Resources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://stackoverflow.com/a/1220118/1424361&#34;&gt;Your problem with Vim is that you don&amp;rsquo;t grok vi&lt;/a&gt; - A concise explanation of what makes vi/vim special, and one of the most popular answers ever on Stack Overflow.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://medium.com/@mkozlows/why-atom-cant-replace-vim-433852f4b4d1&#34;&gt;Why Atom can&amp;rsquo;t replace Vim&lt;/a&gt; - A great piece on the big picture importance of composable commands.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://blog.carbonfive.com/2011/10/17/vim-text-objects-the-definitive-guide/&#34;&gt;Vim Text Objects: The Definitive Guide&lt;/a&gt; - This is a nice rundown of the different text objects available, including some that you can add using plugins.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h4 id=&#34;update&#34;&gt;Update&lt;/h4&gt;
&lt;p&gt;This post is currently on the front page of Hacker News. Feel free to join in the conversation &lt;a href=&#34;https://news.ycombinator.com/item?id=7976493&#34;&gt;there&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Learning Vim in 2014: The Basics</title>
      <link>https://benmccormick.org/2014/06/30/062800.html</link>
      <pubDate>Mon, 30 Jun 2014 07:28:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2014/06/30/062800.html</guid>
      <description>&lt;p&gt;Do you want to be efficient writing code?  Using Vim can be a powerful help.  Using it has let me move more effectively through the process of writing and editing code.  But getting to where I am now was frustrating. Vim resources are scattered across the web, and contain a lot of different advice.  It&amp;rsquo;s tough to figure out how to make Vim work for you.  In my next few posts, I&amp;rsquo;m going to talk about the process of learning a 23 year old programming power tool, and what you need to know in 2014 to be productive with Vim.  Today I&amp;rsquo;ll start with the basics, stuff that goes back all the way to the 1970s, and we&amp;rsquo;ll grow from there.&lt;/p&gt;
&lt;h3 id=&#34;why-has-vim-survived&#34;&gt;Why has Vim Survived?&lt;/h3&gt;
&lt;p&gt;Vim has been around for a while.  Originally released in 1991 as an improvement on vi (which had been around since 1976), it has outlasted a generation of programmers. The software world has changed a lot since 1991.  So why do people still use it?&lt;/p&gt;
&lt;p&gt;Vim provides a system for editing text that is quite simply more powerful than its modern graphical based alternatives.  It asks a lot of its users. To use Vim effectively you have to internalize the syntax for many commands that have better affordances on other editors.  But you&amp;rsquo;re rewarded with a friction-free editing environment.  Vi&amp;rsquo;s commands are fast, composable, and powerful. So let&amp;rsquo;s get started.&lt;/p&gt;
&lt;h3 id=&#34;step-0-setup&#34;&gt;Step 0: Setup&lt;/h3&gt;
&lt;p&gt;The first thing you need to do is install a copy of Vim. If you&amp;rsquo;re on a Linux or Mac system, there is likely already a system copy, but it is probably not up to date.  So use your system&amp;rsquo;s package manager to get the latest version (7.4 at the time of this writing).  For Mac users I recommend using &lt;a href=&#34;http://brew.sh/&#34;&gt;Homebrew&lt;/a&gt; to download &lt;a href=&#34;https://code.google.com/p/macvim/&#34;&gt;MacVim&lt;/a&gt;. Windows users can download the latest executable on &lt;a href=&#34;http://www.vim.org/download.php&#34;&gt;Vim.org&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The second thing you&amp;rsquo;ll need is a vimrc (the file vim uses for configuration).  These files can become quite extensive, setting up many different options, configurations, and plugins.  But we&amp;rsquo;re going to start simple.  Download &lt;a href=&#34;https://gist.github.com/benmccormick/4e4bc44d8135cfc43fc3&#34;&gt;this minimal vimrc file&lt;/a&gt; and install it in the appropriate directory for your OS as instructed.  If you already have a .vimrc file but don&amp;rsquo;t understand it, I&amp;rsquo;d recommend saving it elsewhere and using a minimal one for now. You can then build it out as you learn more.&lt;/p&gt;
&lt;h3 id=&#34;step-1-learn-the-syntax&#34;&gt;Step 1: Learn the Syntax&lt;/h3&gt;
&lt;p&gt;Just like a programming language, the first thing to learn for Vim is the basic syntax.  Vim has a built in tool to help you get comfortable called vimtutor.  It&amp;rsquo;s a text file set up to help you learn to navigate Vim. Once vim is installed you can run it by calling vimtutor on unix-style systems.  On Windows you can follow the instructions &lt;a href=&#34;http://superuser.com/questions/270938/how-to-run-vimtutor-on-windows&#34;&gt;here&lt;/a&gt;. It will take you through a series of 7 lessons that will familiarize you with the basic commands.&lt;/p&gt;
&lt;p&gt;Vim has rather non-standard commands, and it may be frustrating at first adapting to its different terminology and conventions.  The payoff comes slowly, but it does come.&lt;/p&gt;
&lt;h4 id=&#34;modes&#34;&gt;Modes&lt;/h4&gt;
&lt;p&gt;The most important thing to understand is that Vim is a modal editor.  At any given time you&amp;rsquo;re in one of 6 modes.  You will have different abilities and keystrokes available to you in each of these modes.  For right now the key modes to understand are Normal Mode, Insert Mode, and Command line Mode.&lt;/p&gt;
&lt;p&gt;Normal Mode is the default mode.  It&amp;rsquo;s roughly equivalent to the state that other editors are in when you&amp;rsquo;re holding down the ctrl or cmd keys.  Instead of entering text onto the screen, different keys trigger different commands.  Initially this is a bit weird.  Those of us coming from other editors or IDEs are used to being able to type text by default.  The thought is that adding text is the primary task in a text editor.  But Vim treats adding text as sitting on equal footing with editing, deleting and manipulating existing text, and starts us in a mode where we can quickly make any change. To steal an analogy from Drew Neil, normal mode is the opportunity to take our paintbrush off the canvas while we decide our next stroke.&lt;/p&gt;
&lt;p&gt;Insert mode is the equivalent of most editor&amp;rsquo;s normal state.  When you type a key in normal mode, it appears on the screen. You can enter insert mode by pressing &lt;code&gt;i&lt;/code&gt; in visual mode, and exit it by hitting &lt;code&gt;&amp;lt;esc&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Command line mode lets you enter ex-commands, a command line language that complements normal modes shortcuts.  You enter it by hitting &lt;code&gt;:&lt;/code&gt; in normal mode.  Important commands are &lt;code&gt;:w&lt;/code&gt; to write (save) a file, and &lt;code&gt;:q!&lt;/code&gt; to quit.&lt;/p&gt;
&lt;p&gt;The above commands, and an understanding of the modes are enough for you to survive in Vim, and treat it as a sort of awkward Notepad clone.  You can edit files, save them, and quit.  Going through vimtutor will introduce you to many more commands, and a few more modes.  But you can learn those at your own pace.  Right now you want to see what taking time to learn this awkward unfamiliar syntax can buy you.&lt;/p&gt;
&lt;h3 id=&#34;step-2-learn-the-language&#34;&gt;Step 2: Learn the Language&lt;/h3&gt;
&lt;p&gt;Vim&amp;rsquo;s key commands are different than you&amp;rsquo;ll find in other editors like Sublime Text.  They&amp;rsquo;re not a series of standalone actions that you can do one after another to get what you want.  Instead they form a language.&lt;/p&gt;
&lt;p&gt;Vim statements are made up of actions and motions.  The actions are what you&amp;rsquo;re trying to do, the motions are where you want to do them.&lt;/p&gt;
&lt;p&gt;For example let&amp;rsquo;s take the &lt;code&gt;d&lt;/code&gt; action. &lt;code&gt;d&lt;/code&gt; deletes. You can delete a single character by typing &lt;code&gt;dl&lt;/code&gt;.  You can delete 2 characters by typing &lt;code&gt;d2l&lt;/code&gt;. You can delete a whole line by typing &lt;code&gt;dd&lt;/code&gt;, or delete inside a word by typing &lt;code&gt;diw&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Once you learn the d action, you can use it with every motion you know. Similarly, when you learn a new motion, you can then use it with every action you know.&lt;/p&gt;
&lt;p&gt;So if somebody shows me the &lt;code&gt;y&lt;/code&gt; action and tells me that it yanks (copies) text, I&amp;rsquo;ll know I can yank a character with &lt;code&gt;yl&lt;/code&gt; a line with &lt;code&gt;yy&lt;/code&gt; and inside the current word with &lt;code&gt;yiw&lt;/code&gt;.  Each new Vim command is a tool in your toolbox, and since the tools build off of each other they become exponentially more valuable.&lt;/p&gt;
&lt;h3 id=&#34;step-3-learn-the-mindset&#34;&gt;Step 3: Learn the Mindset&lt;/h3&gt;
&lt;p&gt;Vim can make you hyper-efficient.  But to get there you need to know more than just the command combinations available.  You have to shift your mindset.  Vim commands aren&amp;rsquo;t just easy to learn, they&amp;rsquo;re designed to be repeatable.  Bram Moolenar, Vim&amp;rsquo;s creator has listed out &lt;a href=&#34;http://www.moolenaar.net/habits.html&#34;&gt;7 habits of effective text editing&lt;/a&gt;.  The second habit, don&amp;rsquo;t type it twice, is a pretty good summary of the &amp;ldquo;Vim Way&amp;rdquo; of doing things.&lt;/p&gt;
&lt;p&gt;Vim provides a bunch of ways to avoid repetition.  I&amp;rsquo;ll get into them in another post. For now though, let&amp;rsquo;s take a look at &lt;code&gt;.&lt;/code&gt;, the dot command.  The dot command repeats the last action you&amp;rsquo;ve taken. For instance, you can use &lt;code&gt;ciw&lt;/code&gt; to change a word, hit &lt;code&gt;&amp;lt;esc&amp;gt;&lt;/code&gt; to return to normal mode, then move to another word and type &lt;code&gt;.&lt;/code&gt; to replace that word as well.  You are able to avoid retyping the replacement word as well as the &lt;code&gt;ciw&lt;/code&gt; command. You can run the whole replace with one keystroke, regardless of what words you&amp;rsquo;re replacing.  Like other Vim commands, the dot command is small on its own, but gains power as you add more tools to your toolbox.&lt;/p&gt;
&lt;h3 id=&#34;more-resources&#34;&gt;More Resources&lt;/h3&gt;
&lt;p&gt;If you enjoyed this article you&amp;rsquo;ll probably also enjoy&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;http://www.amazon.com/gp/product/1934356980/ref=as_li_tl?ie=UTF8&amp;camp=1789&amp;creative=390957&amp;creativeASIN=1934356980&amp;linkCode=as2&amp;tag=benmccormicko-20&amp;linkId=FE3JFKHYVRYCUOVS&#34;&gt;Practical Vim&lt;/a&gt;&lt;img src=&#34;http://ir-na.amazon-adsystem.com/e/ir?t=benmccormicko-20&amp;l=as2&amp;o=1&amp;a=1934356980&#34; width=&#34;1&#34; height=&#34;1&#34; border=&#34;0&#34; alt=&#34;&#34; style=&#34;border:none !important; margin:0px !important;&#34; /&gt;: This amazing book by Drew Neil, the creator of &lt;a href=&#34;http://vimcasts.org/&#34;&gt;Vimcasts&lt;/a&gt; was the single best resource I found as I learned Vim.  I highly recommend it for anyone who uses Vim.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;http://yehudakatz.com/2010/07/29/everyone-who-tried-to-convince-me-to-use-vim-was-wrong/&#34;&gt;Everyone Who Tried to Convince Me to use Vim was Wrong&lt;/a&gt;: This blog post is another take on how to start learning Vim, by Yehuda Katz, the prolific developer who&amp;rsquo;s a core member of the Rails, EmberJS, and jQuery teams.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/carlhuda/janus&#34;&gt;Janus&lt;/a&gt;: Janus is another Yehuda Katz project.  It&amp;rsquo;s a starting configuration for Vim meant to make it feel more comfortable for developers who want to come in and be productive immediately.  I personally found that it didn&amp;rsquo;t work for me. The plugin list overwhelmed me and prevented me from learning the basics.  But it may be a better fit for some people and is a great place to look to see configuration ideas and plugins that you can try out on your own.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
</description>
    </item>
    
    <item>
      <title>Discovering Vim</title>
      <link>https://benmccormick.org/2014/06/02/170000.html</link>
      <pubDate>Mon, 02 Jun 2014 18:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2014/06/02/170000.html</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve now been using Vim as my primary text editor for the last 9 months.
When I started, I intended to learn it well enough to use in environments that didn&amp;rsquo;t support Sublime Text. In the end though it ended up becoming my single purpose editor for all occasions. Writing code, blogging, diffs, and reading logs all go through vim.  So why do I use Vim?&lt;/p&gt;
&lt;h4 id=&#34;more-efficient-movement-and-editing&#34;&gt;More Efficient Movement and Editing&lt;/h4&gt;
&lt;p&gt;This is the first thing you hear about from experienced Vimmers, and its an important one.  Once you have your feet under you as a Vim user, you are just able to edit faster.  This can be hard to understand before using Vim (or other keyboard based tools).  Using a mouse doesn&amp;rsquo;t feel particularly inefficient, and when you start out, Vim&amp;rsquo;s keyboard mappings can feel arbitrary, unintuitive and slow.  This is one of those times where a little work is needed to get the proper perspective.  Once you&amp;rsquo;ve had time to learn the basics, even a mediocre typist like me &lt;sup id=&#34;fnref:1&#34;&gt;
&lt;a href=&#34;#fn:1&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; can fly when editing by typing smarter not harder.  This isn&amp;rsquo;t a tutorial on the basics of Vim, but the keys for me were understanding Vim was &lt;a href=&#34;http://stackoverflow.com/questions/1218390/what-is-your-most-productive-shortcut-with-vim/1220118#1220118&#34;&gt;a language in its own right&lt;/a&gt;, and the biggest gains in Vim come when you create repeatable options to eliminate inefficiencies. These can be macros, but can also be as simple as using Vim&amp;rsquo;s easy control for repeating the last action&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;.  Vim is a huge toolbox of small tools that you can use together to create a powerful workstation.&lt;/p&gt;
&lt;h4 id=&#34;rich-plugin-ecosystem&#34;&gt;Rich Plugin Ecosystem&lt;/h4&gt;
&lt;p&gt;Like many things in Vim, the value of its plugin system wasn&amp;rsquo;t immediately obvious.  Unlike Sublime, which has a community consensus primary package manager and repository, Vim has multiple package managers that pull packages from a variety of locations&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;.  So you need to do some research to figure out what you should be using&lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34;&gt;5&lt;/a&gt;&lt;/sup&gt; and find the right plugins.  But when you do, you&amp;rsquo;ll find that Vim has fantastic plugins for key tasks like &lt;a href=&#34;https://github.com/kien/ctrlp.vim&#34;&gt;fuzzy file search&lt;/a&gt;, &lt;a href=&#34;https://github.com/scrooloose/syntastic&#34;&gt;syntax checking&lt;/a&gt;, and &lt;a href=&#34;https://github.com/mileszs/ack.vim&#34;&gt;in-file search&lt;/a&gt;.  It also has a rich depth of plugins for pretty much every language/framework/functionality in common usage, as well as some great plugins that extend Vim&amp;rsquo;s built in motion/editing language.&lt;/p&gt;
&lt;h4 id=&#34;long-term-security&#34;&gt;Long Term Security&lt;/h4&gt;
&lt;p&gt;This one is a judgement call, but from my point of view, Vim is the safest investment of my time out there.  It has a rich open source community, one that has shown that its willing to try &lt;a href=&#34;http://neovim.org/&#34;&gt;some big ideas&lt;/a&gt; to keep from getting stale.  It&amp;rsquo;s had a great 20 years of usage and doesn&amp;rsquo;t appear to be in decline.  Sublime Text meanwhile, regrettably seems to be in danger of heading down a similar path to Textmate, with a single developer who has done great work, but &lt;a href=&#34;http://www.sublimetext.com/forum/viewtopic.php?f=2&amp;amp;t=14591&#34;&gt;doesn&amp;rsquo;t appear to be interested&lt;/a&gt; in being involved in all of the different work that a software business requires.  I don&amp;rsquo;t think open source is the only way to rely on software&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;, but for general purpose text editors, Vim seems the safest bet to still be around in 10 years.&lt;/p&gt;
&lt;h4 id=&#34;my-brain-is-broken-now&#34;&gt;My Brain is Broken Now&lt;/h4&gt;
&lt;p&gt;This is a warning as much as a reason for using Vim, but I&amp;rsquo;ve quickly found that I&amp;rsquo;m no longer able to use Sublime or other editors without being frustrated by the fact that they&amp;rsquo;re not Vim.  Many editors, including Sublime, provide support for a large subset of Vim&amp;rsquo;s key bindings and modal controls.  But they all fall down at random places.  The power of vim doesn&amp;rsquo;t lie in one specific functionality, but the composable nature of their different options.  When some of them aren&amp;rsquo;t there, all the others are weakened, and my trained brain falls out of high efficiency mode into slow plodding &amp;ldquo;think through every keystroke mode.&amp;rdquo;  So don&amp;rsquo;t say I didn&amp;rsquo;t warn you.  Vim will break your brain.&lt;/p&gt;
&lt;p&gt;Those are the primary reasons I use Vim now.  There are a few things I haven&amp;rsquo;t loved though.&lt;/p&gt;
&lt;h4 id=&#34;vims-ui-is-uglier-than-sublime-text&#34;&gt;Vim&amp;rsquo;s UI is uglier than Sublime Text.&lt;/h4&gt;
&lt;p&gt;I&amp;rsquo;m a front end developer, used to working with, and working to create, beautiful interfaces.  Vim is not beautiful.  It looks like exactly what it is, a text based program with a lineage reaching back to the 70s.  It doesn&amp;rsquo;t handle margins or padding well, doesn&amp;rsquo;t have pretty autocomplete menus or visual alerts.  If you use it in the terminal you may be severely restricted in your color options, and this situation is not something that is going to change anytime soon&lt;sup id=&#34;fnref:6&#34;&gt;&lt;a href=&#34;#fn:6&#34;&gt;6&lt;/a&gt;&lt;/sup&gt;.  I still love Sublime Text&amp;rsquo;s UI.  Nice margins, smooth scrolling, the ability to set different font and syntax highlighting options on a filetype basis are all nice gems that Vim just doesn&amp;rsquo;t offer.  I&amp;rsquo;ve come to appreciate Vim&amp;rsquo;s minimalism, but would love to see if Neovim were to offer a way to beautify some of these things.&lt;/p&gt;
&lt;h4 id=&#34;vim-is-harder-to-learn-than-it-should-be&#34;&gt;Vim is harder to learn than it should be.&lt;/h4&gt;
&lt;p&gt;I&amp;rsquo;ve seen some Vimmers object to this (its a power user tool, etc.) but the truth is, when pretty much every Vim tutorial starts by telling you that you should start by changing a bunch of the default settings, it becomes clear that learning Vim is harder than it should be. There&amp;rsquo;s no reason that basics like line numbers and syntax highlighting shouldn&amp;rsquo;t be turned on by default.  Configurability is great, but if you start out in a user-hostile state, many people won&amp;rsquo;t take the time to find the power.  There have been some efforts to change that.  Neovim seems to be actively rethinking this stuff, and projects like &lt;a href=&#34;https://github.com/carlhuda/janus&#34;&gt;Janus&lt;/a&gt; aim to help people get started with a richer initial setup.  But the very existence of these reforms points to the fact that Vim shoots itself in the foot with defaults that may have made sense in the eighties, but appear archaic next to modern competitors.&lt;/p&gt;
&lt;p&gt;For now I&amp;rsquo;m enjoying the Vim experience.  Despite a few warts, I really do think its the best text editor you can use today, and I&amp;rsquo;m excited to see where it goes in the future.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34;&gt;
&lt;ol&gt;
&lt;li class=&#34;footnote&#34; id=&#34;fn:1&#34;&gt;
        &lt;p&gt;
I was never taught to type correctly growing up. Apparently this is unusual in my generation.  Early last year I decided to ditch my hunt and peck 5 finger style for &#34;the proper way.&#34;  It was a great learning experience.  I now muddle along at a mediocre 62 WPM according to online typing tests.
    	&lt;a href=&#34;#fnref:1&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
&lt;li class=&#34;footnote&#34; id=&#34;fn:2&#34;&gt;
&lt;p&gt;
I highly recommend Drew Neil&#39;s Practical Vim for anyone who wants to get serious about using Vim.  It taught me about the power of repetition in Vim as well as how to formulate Vim&#39;s many disparate features into a coherent text editing philosophy.
&lt;a href=&#34;#fnref:2&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li class=&#34;footnote&#34; id=&#34;fn:3&#34;&gt;
&lt;p&gt;
Yes there&#39;s an official repository, but have you been on Vim.org&#39;s repository?  Its an ugly frustrating site that does nothing to highlightuseful plugins.  It also often contains information that is less up-to-date than the plugins github README, and some important packages like ctrlp are not represented there.        
&lt;p&gt;&lt;a href=&#34;#fnref:3&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li class=&#34;footnote&#34; id=&#34;fn:4&#34;&gt;
&lt;p&gt;
I&#39;d have no problem investing time in IntelliJ or Visual Studio for instance if I felt like a heavy IDE like that was the way to go, and that they&#39;d add productivity to justify their cost.  They have established companies backing them that are able to do things like respond to customer feedback, provide product roadmaps, etc.
&lt;p&gt;&lt;a href=&#34;#fnref:4&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li class=&#34;footnote&#34; id=&#34;fn:5&#34;&gt;
 &lt;p&gt;
  Hint: Use Vundle
&lt;p&gt;&lt;a href=&#34;#fnref:5&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li class=&#34;footnote&#34; id=&#34;fn:6&#34;&gt;
&lt;p&gt;
Due to the terminal compatibility requirement
&lt;a href=&#34;#fnref:6&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Digging Into Knockout Builds</title>
      <link>https://benmccormick.org/2014/01/06/183000.html</link>
      <pubDate>Mon, 06 Jan 2014 19:30:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2014/01/06/183000.html</guid>
      <description>&lt;p&gt;There&amp;rsquo;s a lot you can learn by looking through other people&amp;rsquo;s code.  This is especially true when you&amp;rsquo;re looking at widely used open-source libraries, where you can see how people have solved real problems with code that has been battle-tested and debated.&lt;/p&gt;
&lt;p&gt;In this spirit of code literacy, I spent some time this past weekend to look through the source code for &lt;a href=&#34;http://knockoutjs.com/&#34;&gt;KnockoutJS&lt;/a&gt;.  Knockout is a MVVM library in Javascript designed to make 2 way declarative bindings easy.  I&amp;rsquo;m wanted to write a bit about what I saw in Knockout&amp;rsquo;s structure and build process.&lt;/p&gt;
&lt;h3 id=&#34;intro&#34;&gt;Intro&lt;/h3&gt;
&lt;p&gt;Some of the first decisions a developer has to make when starting a new javascript project revolve around project structure and build processes.  They need to decide how they&amp;rsquo;ll handle things like testing and minification.  For a library like Knockout, developers also need to figure out how to make sure that they don&amp;rsquo;t expose any internal logic to the global scope.  This post takes a look at how Knockout deals with these challenges.  You can follow along by getting &lt;a href=&#34;https://github.com/knockout/knockout&#34;&gt;the source&lt;/a&gt; off of Github.&lt;/p&gt;
&lt;h3 id=&#34;project-structure&#34;&gt;Project Structure&lt;/h3&gt;
&lt;p&gt;Knockout is organized with a traditional &lt;code&gt;src&lt;/code&gt;,&lt;code&gt;spec&lt;/code&gt;,&lt;code&gt;build&lt;/code&gt; structure, with the main src code in the src directory, &lt;a href=&#34;http://pivotal.github.io/jasmine/&#34;&gt;Jasmine&lt;/a&gt; tests in the spec directory, and build-related files in the build directory.  The src directory is fairly flat, with directories for bindings, templating and subscribables.  The spec directory does not mirror it exactly.  The spec files are organized around functional categories at the root of the source files, with a separate directory holding tests for the default bindings.   The build direction contains several files related to the build process, which I&amp;rsquo;ll discuss below.  In the root directory there are dotfiles for &lt;a href=&#34;https://npmjs.org/&#34;&gt;NPM&lt;/a&gt;, &lt;a href=&#34;http://git-scm.com/&#34;&gt;git&lt;/a&gt;, and &lt;a href=&#34;http://about.travis-ci.org/&#34;&gt;TravisCI&lt;/a&gt;, a package.json file, and the gruntfile.&lt;/p&gt;
&lt;h3 id=&#34;grunt&#34;&gt;Grunt&lt;/h3&gt;
&lt;p&gt;Knockout&amp;rsquo;s build process is automated using Grunt, an automation tool built on &lt;a href=&#34;xmpux.cisco.com&#34;&gt;NodeJS&lt;/a&gt;.  Knockout&amp;rsquo;s gruntfile weighs in at a very readable 150 lines of code, and only defines one task.  That default task looks like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;//Grunt Default Task
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;grunt.registerTask(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;default&amp;#39;&lt;/span&gt;, [&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;clean&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;checktrailingspaces&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;build&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;test&amp;#39;&lt;/span&gt;]);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So when you build knockout you&amp;rsquo;re executing 4 steps.&lt;/p&gt;
&lt;h4 id=&#34;clean&#34;&gt;Clean&lt;/h4&gt;
&lt;p&gt;This deletes the knockout-latest.debug.js and knockout-latest.min.js files from the &lt;code&gt;build/output&lt;/code&gt; directory&lt;/p&gt;
&lt;h4 id=&#34;check-trailing-spaces&#34;&gt;Check Trailing Spaces&lt;/h4&gt;
&lt;p&gt;This checks source files for trailing spaces and throws an error if they exist, ending the build.&lt;/p&gt;
&lt;h4 id=&#34;build&#34;&gt;Build&lt;/h4&gt;
&lt;p&gt;More detail on this below.&lt;/p&gt;
&lt;h4 id=&#34;test&#34;&gt;Test&lt;/h4&gt;
&lt;p&gt;Test spawns a child process which calls 2 scripts: &amp;lsquo;spec/runner.phantom.js&amp;rsquo; and &amp;lsquo;spec/runner.node.js&amp;rsquo;.  The script runs asynchronously in the background, with the results being passed to standard out through a callback.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;//Grunt Test Task
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;grunt.initConfig({
    &lt;span style=&#34;color:#6272a4&#34;&gt;//...
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    test&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; {
        phantomjs&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;spec/runner.phantom.js&amp;#39;&lt;/span&gt;,
        node&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;spec/runner.node.js&amp;#39;&lt;/span&gt;
    }
});

grunt.registerMultiTask(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;test&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Run tests&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt; () {
    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; done &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.&lt;span style=&#34;color:#ff79c6&#34;&gt;async&lt;/span&gt;();
    grunt.util.spawn({ cmd&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.target, args&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; [&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.data] },
        &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt; (error, result, code) {
            &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (code &lt;span style=&#34;color:#ff79c6&#34;&gt;===&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;127&lt;/span&gt; &lt;span style=&#34;color:#6272a4&#34;&gt;/*not found*/&lt;/span&gt;) {
                grunt.verbose.error(result.stderr);
                &lt;span style=&#34;color:#6272a4&#34;&gt;// ignore this error
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;                done(&lt;span style=&#34;color:#ff79c6&#34;&gt;true&lt;/span&gt;);
            } &lt;span style=&#34;color:#ff79c6&#34;&gt;else&lt;/span&gt; {
                grunt.log.writeln(result.stdout);
                &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (error)
                    grunt.log.error(result.stderr);
                done(&lt;span style=&#34;color:#ff79c6&#34;&gt;!&lt;/span&gt;error);
            }
        }
    );
});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Overall a few things stand out about Knockout&amp;rsquo;s gruntfile.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;It&amp;rsquo;s written with no dependencies other than the base grunt-cli package, which is specifically called out in package.json to be run locally.  This is in sharp contrast to most Grunt-based projects I&amp;rsquo;ve seen, which assume a global install of Grunt and then make heavy use of the Grunt plugin ecosystem.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The only code consistency check is flagging trailing whitespace. Rather than enforce styling with a tool like jsHint, the build process only protects the integrity of the diffs with the whitespace check. This is probably a consequence of the plugin-free build file set up.  Overall the build philosophy seems to aim to keep things as simple as possible.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;the-build-process&#34;&gt;The Build Process&lt;/h3&gt;
&lt;p&gt;So what happens with the build command?  When it&amp;rsquo;s executed the build command runs a task which creates 2 files, knockout-latest.debug.js and knockout-latest.min. Each of them contain the same content, with the debug version wrapped in an &lt;a href=&#34;http://benalman.com/news/2010/11/immediately-invoked-function-expression/&#34;&gt;IIFE&lt;/a&gt;, and the minified version run through Google closure compiler.&lt;/p&gt;
&lt;p&gt;The content is pulled together with the &lt;code&gt;getCombinedSources&lt;/code&gt; function:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;//Grunt Build Task
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt; getCombinedSources() {
    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; fragments &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; grunt.config(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;fragments&amp;#39;&lt;/span&gt;),
        sourceFilenames &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; [
            fragments &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;extern-pre.js&amp;#39;&lt;/span&gt;,
            fragments &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;amd-pre.js&amp;#39;&lt;/span&gt;,
            getReferencedSources(fragments &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;source-references.js&amp;#39;&lt;/span&gt;),
            fragments &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;amd-post.js&amp;#39;&lt;/span&gt;,
            fragments &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;extern-post.js&amp;#39;&lt;/span&gt;
        ],
        flattenedSourceFilenames &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;Array&lt;/span&gt;.prototype.concat.apply([], sourceFilenames),
        combinedSources &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; flattenedSourceFilenames.map(&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(filename) {
            &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; grunt.file.read(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;./&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; filename);
        }).join(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;);

    &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; combinedSources.replace(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;##VERSION##&amp;#39;&lt;/span&gt;, grunt.config(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;pkg.version&amp;#39;&lt;/span&gt;));
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So this takes each of the files returned by the getReferencedSources function, and wraps them with 2 more files on each side.  Lets look at the wrapper files first.&lt;/p&gt;
&lt;p&gt;extern-pre.js sets up an IIFE and defines several global values within the local scope.  This is done in order to protect against any reuse of these names in the local scope where knockout is loaded.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;//extern-pre.js
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;(&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(&lt;span style=&#34;color:#ff79c6&#34;&gt;undefined&lt;/span&gt;){
    &lt;span style=&#34;color:#6272a4&#34;&gt;// (0, eval)(&amp;#39;this&amp;#39;) is a robust way of getting a reference to the global object
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#6272a4&#34;&gt;// For details, see http://stackoverflow.com/questions/14119988/return-this-0-evalthis/14120023#14120023
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;window&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;||&lt;/span&gt; (&lt;span style=&#34;color:#bd93f9&#34;&gt;0&lt;/span&gt;, &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;eval&lt;/span&gt;)(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;this&amp;#39;&lt;/span&gt;),
        &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;document&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;window&lt;/span&gt;[&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;document&amp;#39;&lt;/span&gt;],
        navigator &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;window&lt;/span&gt;[&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;navigator&amp;#39;&lt;/span&gt;],
        jQuery &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;window&lt;/span&gt;[&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;jQuery&amp;#34;&lt;/span&gt;],
        JSON &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;window&lt;/span&gt;[&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;JSON&amp;#34;&lt;/span&gt;];
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;amd-pre.js determines the type of module system in use (if any) and passes the correct object into the inner scope as koExports.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;//amd-pre.js
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;(&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(factory) {
  &lt;span style=&#34;color:#6272a4&#34;&gt;// Support three module loading scenarios
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#ff79c6&#34;&gt;typeof&lt;/span&gt; require &lt;span style=&#34;color:#ff79c6&#34;&gt;===&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;function&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;typeof&lt;/span&gt; exports &lt;span style=&#34;color:#ff79c6&#34;&gt;===&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;object&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;typeof&lt;/span&gt; module &lt;span style=&#34;color:#ff79c6&#34;&gt;===&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;object&amp;#39;&lt;/span&gt;) {
    &lt;span style=&#34;color:#6272a4&#34;&gt;// [1] CommonJS/Node.js
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; target &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; module[&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;exports&amp;#39;&lt;/span&gt;] &lt;span style=&#34;color:#ff79c6&#34;&gt;||&lt;/span&gt; exports; &lt;span style=&#34;color:#6272a4&#34;&gt;//module.exports is for Node.js
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    factory(target);
  } &lt;span style=&#34;color:#ff79c6&#34;&gt;else&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#ff79c6&#34;&gt;typeof&lt;/span&gt; define &lt;span style=&#34;color:#ff79c6&#34;&gt;===&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;function&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; define[&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;amd&amp;#39;&lt;/span&gt;]) {
    &lt;span style=&#34;color:#6272a4&#34;&gt;// [2] AMD anonymous module
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    define([&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;exports&amp;#39;&lt;/span&gt;], factory);
  } &lt;span style=&#34;color:#ff79c6&#34;&gt;else&lt;/span&gt; {
    &lt;span style=&#34;color:#6272a4&#34;&gt;// [3] No module loader (plain &amp;lt;script&amp;gt; tag) - put directly in global namespace
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    factory(&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;window&lt;/span&gt;[&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;ko&amp;#39;&lt;/span&gt;] &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {});
  }
})
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The *-post.js files simply close these function statements.&lt;/p&gt;
&lt;p&gt;So in the end we&amp;rsquo;re left with an IIFE that wraps all of the content and defines global variables within the scope, and then executes a second IIFE which determines the module format in use and executes the inner factory function accordingly.  The factory function is made up of the various files in the src directory, concatenated together in the order specified in build/fragments/source-references.js.&lt;/p&gt;
&lt;h3 id=&#34;initializing-the-library&#34;&gt;Initializing the library&lt;/h3&gt;
&lt;p&gt;The first few files loaded into the inner function are short files designed to provide a base for the library.&lt;/p&gt;
&lt;p&gt;namespace.js sets up the ko object that is referenced internally in the file.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;//namespace.js
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;// Internally, all KO objects are attached to koExports (even the non-exported ones whose names will be minified by the closure compiler).
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;// In the future, the following &amp;#34;ko&amp;#34; variable may be made distinct from &amp;#34;koExports&amp;#34; so that private objects are not externally reachable.
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; ko &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;typeof&lt;/span&gt; koExports &lt;span style=&#34;color:#ff79c6&#34;&gt;!==&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;undefined&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;?&lt;/span&gt; koExports &lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; {};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;google-closure-compiler-utils.js defines two helper functions, exportSymbol and exportProperty which allow for greater minimization of the internal ko library while maintaining a consistent external api.  These functions are used everywhere throughout the library for defining externally facing function and property names.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;//google-closure-compiler-utils.js
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;
&lt;span style=&#34;color:#6272a4&#34;&gt;// Google Closure Compiler helpers (used only to make the minified file smaller)
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;ko.exportSymbol &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(koPath, object) {
    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; tokens &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; koPath.split(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;.&amp;#34;&lt;/span&gt;);

    &lt;span style=&#34;color:#6272a4&#34;&gt;// In the future, &amp;#34;ko&amp;#34; may become distinct from &amp;#34;koExports&amp;#34; (so that non-exported objects are not reachable)
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#6272a4&#34;&gt;// At that point, &amp;#34;target&amp;#34; would be set to: (typeof koExports !== &amp;#34;undefined&amp;#34; ? koExports : ko)
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; target &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; ko;

    &lt;span style=&#34;color:#ff79c6&#34;&gt;for&lt;/span&gt; (&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; i &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;0&lt;/span&gt;; i &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt; tokens.length &lt;span style=&#34;color:#ff79c6&#34;&gt;-&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;; i&lt;span style=&#34;color:#ff79c6&#34;&gt;++&lt;/span&gt;)
        target &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; target[tokens[i]];
    target[tokens[tokens.length &lt;span style=&#34;color:#ff79c6&#34;&gt;-&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;]] &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; object;
};
ko.exportProperty &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(owner, publicName, object) {
  owner[publicName] &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; object;
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Finally version.js sets up a placeholder for ko.version, which is then replaced with the version number in Package.json as part of the grunt build task.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;//version.js
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;ko.version &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;##VERSION##&amp;#34;&lt;/span&gt;;

ko.exportSymbol(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;version&amp;#39;&lt;/span&gt;, ko.version);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;There are a few interesting things we can note from Knockout&amp;rsquo;s build approach.&lt;/p&gt;
&lt;h4 id=&#34;using-iifes-to-isolate-local-scope-is-a-practical-and-important-technique-for-library-design&#34;&gt;Using IIFE&amp;rsquo;s to isolate local scope is a practical and important technique for library design&lt;/h4&gt;
&lt;p&gt;If you&amp;rsquo;ve been counting, the debug version of the library is wrapped in 3 different levels of IIFEs before any code exposing external functionality is actually included.  This allows Knockout to provide several layers of data protection and abstraction, making sure that it is referencing the correct global variables and preventing scope leaks.&lt;/p&gt;
&lt;h4 id=&#34;its-relatively-straightforward-to-support-module-formats-even-if-your-library-doesnt-use-them-internally&#34;&gt;Its relatively straightforward to support module formats even if your library doesn&amp;rsquo;t use them internally&lt;/h4&gt;
&lt;p&gt;Take a look again at amd-pre.js.  Its 15 lines of code to support AMD loaders, CommonJS loaders and normal script tag loading.  Knockout doesn&amp;rsquo;t use a modern &amp;ldquo;module solution&amp;rdquo; approach to code organization.  Instead it uses a more traditional namespacing approach wrapped in IIFEs.  But it still plays well with others nicely.  It&amp;rsquo;s hard to see how this type of effort wouldn&amp;rsquo;t be worth it for library designers.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Meetings And Concurrency</title>
      <link>https://benmccormick.org/2013/12/30/060000.html</link>
      <pubDate>Mon, 30 Dec 2013 07:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2013/12/30/060000.html</guid>
      <description>&lt;p&gt;Working with a large number of people on any significant project eventually involves meetings.  You can delay it for a while, and you can try to replace them with all sorts of things, including email, IM, wikis, and guessing people&amp;rsquo;s intentions.  Doing so is, of course, completely worthwhile.  Eventually though, meetings are inevitable.&lt;/p&gt;
&lt;p&gt;There are several different flavors of meetings.  There are decision-making meetings, where a crowd of people gather together, either to argue, watch other people argue, or to carefully watch the hands of the clock make their way around its circumference. There are Powerpoint meetings, wherein an individual gathers his victims (sorry was that coworkers?) together and proceeds to read bullet points from a set of slides to them.  There is also the conference call meeting, which has led many people to a deeper appreciation for the mute button on their phone.  Rarest of all is the actual productive meeting, where information is exchanged, decisions are made, and life continues without irreparable harm.&lt;/p&gt;
&lt;p&gt;So is there any hope for productive meetings?  It&amp;rsquo;s important to realize that a meeting should be the last resort for most things.  Meetings are blocking synchronous activities.  Everyone gives up a set piece of time and that time is the same for everyone. The meeting length is limited by the attendee most willing to keep talking. Generally that time cannot be used for anything else by the people involved in the meeting.&lt;/p&gt;
&lt;p&gt;Programmers have several options for handling long running blocking operations while coding.  The first is the naive approach.  The following coffeescript is an example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-coffeescript&#34; data-lang=&#34;coffeescript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;meetingDone = &lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;false&lt;/span&gt;

&lt;span style=&#34;color:#6272a4&#34;&gt;# are we done yet?
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;until&lt;/span&gt; meetingDone
    &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; person1Ready() &lt;span style=&#34;color:#ff79c6&#34;&gt;and&lt;/span&gt; person2Ready() &lt;span style=&#34;color:#ff79c6&#34;&gt;and&lt;/span&gt; person3Ready()
        longRunningMeeting()

&lt;span style=&#34;color:#6272a4&#34;&gt;#Do whatever&amp;#39;s next, plus anything that depends on the meeting
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;followUpOnMeeting()
backToWork()
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is how things often work when it comes to meetings, but that code wouldn&amp;rsquo;t last long in a professional software environment.  Everything grinds to a halt until the meeting is done, which keeps the program from doing anything else or responding to user input.&lt;/p&gt;
&lt;p&gt;A second option while coding is the multi-threaded approach.  In coffeescript that looks something like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-coffeescript&#34; data-lang=&#34;coffeescript&#34;&gt;
&lt;span style=&#34;color:#6272a4&#34;&gt;# Do meeting tasks in a worker thread
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;meeting = &lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; Worker &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;meeting.js&amp;#34;&lt;/span&gt;

&lt;span style=&#34;color:#6272a4&#34;&gt;# When the meeting is done, act on a follow up message
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;meeting.addEventListener &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;message&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#50fa7b&#34;&gt;(e) -&amp;gt;&lt;/span&gt;
    followUpOnMeeting(e.data)

meeting.postMessage &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;Start&amp;#34;&lt;/span&gt;

&lt;span style=&#34;color:#6272a4&#34;&gt;# get back to work right away
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;backToWork()
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is equivalent in the real world to limiting the people in a meeting.  Rather than allowing a meeting to block all our resources, we put only some of our resources into the meeting and then pass the results of the meeting on to the rest of the team once the meeting is complete.&lt;/p&gt;
&lt;p&gt;This is an important principle for meetings. Meetings should contain the minimum amount of people needed to accomplish their purpose.  When meetings grow beyond that size (due to laziness, politics, process or confusion) they begin to become exponentially less productive.&lt;/p&gt;
&lt;p&gt;Of course multi-threaded approaches can still suffer the same issues as single threaded programs if you try to do too much.  If the worker thread in the example above looks like the code below, we will not have gained much.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-coffeescript&#34; data-lang=&#34;coffeescript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;# meeting.coffee
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;self.addEventListener &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;message&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#50fa7b&#34;&gt;(e) -&amp;gt;&lt;/span&gt;
    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;somebodyHasMadeADecision = &lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;false&lt;/span&gt;

    &lt;span style=&#34;color:#6272a4&#34;&gt;# are we done yet?
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#ff79c6&#34;&gt;until&lt;/span&gt; somebodyHasMadeADecision
        &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt;  person1Indecisive() &lt;span style=&#34;color:#ff79c6&#34;&gt;and&lt;/span&gt; person2Scared() &lt;span style=&#34;color:#ff79c6&#34;&gt;and&lt;/span&gt; person3Clueless()
            longRunningMeeting()

    self.postMessage &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;meeting is finally done&amp;#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;No matter who is involved it&amp;rsquo;s important for meetings to have a clear purpose.  Just like you wouldn&amp;rsquo;t put all of your program&amp;rsquo;s logic inside a single worker thread, the best meetings are simple, single purposed, and lightweight, based on clear, answerable questions.&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s a third approach that programmers can take to long running processes.  They can use asynchronous operations, as shown below using promise notation.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-coffeescript&#34; data-lang=&#34;coffeescript&#34;&gt;
&lt;span style=&#34;color:#6272a4&#34;&gt;# define an email response function
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;readResponses = &lt;/span&gt;&lt;span style=&#34;color:#50fa7b&#34;&gt;(message) -&amp;gt;&lt;/span&gt;
    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;respond = &lt;/span&gt;readEmail()
    &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; respond &lt;span style=&#34;color:#ff79c6&#34;&gt;then&lt;/span&gt; respondToEmail()

sendEmail(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;importantTopic&amp;#34;&lt;/span&gt;)
    &lt;span style=&#34;color:#6272a4&#34;&gt;# responses and respond if necessary
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    .then(readResponses)
    &lt;span style=&#34;color:#6272a4&#34;&gt;# read more responses and respond if necessary
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    .then(readResponses)
    &lt;span style=&#34;color:#6272a4&#34;&gt;# follow up when the responses are done
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    .done followUpOnMeeting

&lt;span style=&#34;color:#6272a4&#34;&gt;# After email we can go back to work right away
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;backToWork();
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This async approach doesn&amp;rsquo;t delegate different resources for different problems, instead we change how we&amp;rsquo;re thinking about long running operations.  Rather than tying up resources to deal with them, we make them a separate operation that can be consumed and responded to when our program has available time. You can&amp;rsquo;t do that with meetings.&lt;/p&gt;
&lt;p&gt;By contrast, email, documentation, and other &amp;ldquo;information artifacts&amp;rdquo; can be consumed asynchronously, at different paces and different times by different people. They don&amp;rsquo;t block off any particular time that might need to be devoted to other things.  So Powerpoint meetings can become an email that contains a Powerpoint or wiki page, followed if necessary by clarifying questions which people can work through at their own pace. Decision meetings can become a back and forth discussion on a mailing list, that the interested parties can participate in as they have time and motivation.  It removes blocking issues completely by removing the requirement of all participants being on the same time schedule.&lt;/p&gt;
&lt;p&gt;So the takeaways from this coffee flavored reflection on meetings:  Async operations are your friends.  Don&amp;rsquo;t have meetings.  If you do, keep them short, small, and focused. Friends don&amp;rsquo;t let friends read their powerpoint slides line by line.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>A look at Ack</title>
      <link>https://benmccormick.org/2013/11/25/185000.html</link>
      <pubDate>Mon, 25 Nov 2013 19:50:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2013/11/25/185000.html</guid>
      <description>&lt;p&gt;Do you spend a lot of time searching your projects for a specific piece of code?  Frustrated by grep&amp;rsquo;s weird syntax or slow IDE search tools?  &lt;a href=&#34;http://beyondgrep.com/&#34;&gt;Ack&lt;/a&gt; is a tool like grep designed for programmers.  I use it for searching my source code to track down sections of code or look for occurences of a variable or reference.  It&amp;rsquo;s a simple open-source tool that does one job well, and does it with blazing speed.&lt;/p&gt;
&lt;p&gt;Ack performs a subset of grep&amp;rsquo;s functionality, optimizing for the programmer&amp;rsquo;s use case. In the simplest usage it will allow you to enter an expression, and will search files in the current directory/subdirectory for it, ignoring version control artifacts like .svn and .git files.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# search all files in current directory recursively
# to see if they contain &amp;quot;foobar&amp;quot;
ack foobar
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ack then spits out nicely formatted output with the full file paths and line numbers of each occurence. For instance here is the output of searching the directory containing my blog posts for references to Microsoft.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;ack_msft.png&#34; alt=&#34;ack usage example&#34;&gt;&lt;/p&gt;
&lt;p&gt;These are very simple examples.  Because of ack&amp;rsquo;s sensible defaults and focused design, these basic commands cover about 80% of what I&amp;rsquo;m looking for from a code search tool. But for those who want to do a bit more, ack can be much more powerful.  Because ack is written in perl, any perl-compatible regular expression can be used to search your files.  Ack provides plenty of options for formatting the output and it&amp;rsquo;s also very easy to filter by filetype.&lt;/p&gt;
&lt;p&gt;For instance, I have a small side project where I&amp;rsquo;m creating an event signup site with the front end code written in CoffeeScript.  If I want to see which files I&amp;rsquo;ve referenced events in without necessarily seeing all the details, I can use the &lt;code&gt;-l&lt;/code&gt; flag to only show file names.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;ack_signup.png&#34; alt=&#34;filenames only&#34;&gt;&lt;/p&gt;
&lt;p&gt;Obviously this search brings up several types of files. Along with the CoffeeScript files I&amp;rsquo;m interested in, ack shows some html and css files, as well as a random server side file.  It also shows the generated JavaScript files.  I could get rid of these files by specifying a different root directory, but instead I&amp;rsquo;m going to show ack&amp;rsquo;s  smart filtering by filetype.  To search only coffeescript files, I just need to add the &lt;code&gt;--coffee&lt;/code&gt; flag to see all CoffeeScript matches.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;ack_event.png&#34; alt=&#34;ack filetype filtering&#34;&gt;&lt;/p&gt;
&lt;p&gt;Its also easy to add multiple filetype flags in order to search several filetypes, and you can even define custom filetype flags with an .ackrc file.  These also let you specify default options and set certain directories to be ignored on a global or per-project basis.&lt;/p&gt;
&lt;h4 id=&#34;other-options&#34;&gt;Other Options&lt;/h4&gt;
&lt;p&gt;Ack is hardly the only code search tool out there.  It&amp;rsquo;s meant to improve on grep by focusing on the programmer&amp;rsquo;s use cases, but there are &lt;del&gt;many&lt;/del&gt; some situations where grep is still a good option.  Ack is situationally optimized for searching code, &lt;del&gt;and doesn&amp;rsquo;t work as well for filtering piped output&lt;/del&gt;. Grep is also installed on many remote servers where you won&amp;rsquo;t have access to ack.  So ack makes a great complement to grep, moreso than a replacement.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Update: You can totally use Ack to filter piped output.  Another reason to use grep gone.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;In terms of direct competition, &lt;a href=&#34;https://github.com/ggreer/the_silver_searcher&#34;&gt;ag&lt;/a&gt; is an attempt to improve on ack, mostly in terms of speed. Ag uses various tricks to optimize speed performance for code search, using an ack compatible syntax. Since its written in C rather than perl, it is indeed significantly faster.  I personally am more comfortable with ack.  Its more mature, has better documentation, and has always been fast enough for me.&lt;/p&gt;
&lt;p&gt;&lt;del&gt;Ag was not updated to support ack 2&amp;rsquo;s filetype filtering, and generally seems to have focused on speed over all else.&lt;/del&gt;  It also has dependencies that I&amp;rsquo;ve found are a problem on old operating systems. Ack only depends on perl, and is thus very portable, even to Windows systems.  Still, if you find ack to be slow on your code base, or just like knowing you&amp;rsquo;re doing everything as fast as possible, ag is a great alternative.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Update: As of version 0.22.0 ag supports ack&amp;rsquo;s filetype syntax, but does not allow you to define custom file types, a very useful ack feature.&lt;/em&gt;&lt;/p&gt;
&lt;h4 id=&#34;summary&#34;&gt;Summary&lt;/h4&gt;
&lt;p&gt;If you&amp;rsquo;ve been using grep or slow GUI tools to search your source code, you can do better. Ack is fast, easy to use, and optimized for programmers.  It&amp;rsquo;s also free, open-source code you can use without cost or licensing worries.  If you want to go even faster, consider using ag.  Just make sure you&amp;rsquo;re using a tool that was built for the work you&amp;rsquo;re doing.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Modern Dojo: Exploring declare</title>
      <link>https://benmccormick.org/2013/11/14/181500.html</link>
      <pubDate>Thu, 14 Nov 2013 19:15:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2013/11/14/181500.html</guid>
      <description>&lt;p&gt;This is part 2 of my ongoing exploration of &lt;a href=&#34;http://dojotoolkit.org/&#34;&gt;Dojo&lt;/a&gt;&amp;rsquo;s important modules and concepts.  Specifically this post will be examining dojo/_base/declare, Dojo&amp;rsquo;s object oriented programming helper module.&lt;/p&gt;
&lt;h2 id=&#34;what-is-dojo_basedeclare-used-for&#34;&gt;What is dojo/_base/declare used for?&lt;/h2&gt;
&lt;p&gt;dojo/_base/declare (henceforth &amp;ldquo;declare&amp;rdquo;) is the Dojo module for dom assisting with Object Oriented Programming.  It provides a function that allows for easy &amp;ldquo;classical style&amp;rdquo; inheritance, as well as mixins.  It is fairly flexible, and there seem to be several ways to use it.  I&amp;rsquo;m going to explore those here.&lt;/p&gt;
&lt;h2 id=&#34;how-do-you-use-declare&#34;&gt;How do you use declare?&lt;/h2&gt;
&lt;p&gt;Dojo&amp;rsquo;s declare function takes up to 3 arguments.  The first argument, which is optional, gives a fully qualified namespaced class name &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; rel=&#34;footnote&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.  The second argument is a string or an array specifying a class or set of classes that the new class will inherit from.  This argument can also be null.  The final argument is an object with the properties we want the new class to contain.  The full 3 argument syntax looks like the example below.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;//declare with a className argument
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;
&lt;span style=&#34;color:#6272a4&#34;&gt;//pull in the declare module
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;require([&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;dojo/_base/declare&amp;#34;&lt;/span&gt;], &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(declare) {

  &lt;span style=&#34;color:#6272a4&#34;&gt;//we&amp;#39;re going to create a class in the global myApp namespace
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;  declare(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;myApp.examples.Messenger&amp;#34;&lt;/span&gt;,&lt;span style=&#34;color:#ff79c6&#34;&gt;null&lt;/span&gt;, {
    message&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;hello world&amp;#34;&lt;/span&gt;,
    sendMessage&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;() {
        console.log(message);
    }
  });
  &lt;span style=&#34;color:#6272a4&#34;&gt;//since our class was created globally, we can access it wherever
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#6272a4&#34;&gt;//we want, by refering to the namespace property
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; messenger &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; myApp.examples.Messenger();
  messenger.sendMessage();
});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This syntax works fine, but to me it seems fairly contrary to the spirit of Modern Dojo.  Rather than keeping the class definition bound in a module, it is instead pushed out as a global, using namespacing techniques rather than AMD style modules for code organization.  It seems to be solely a product of supporting legacy implementations and Dojo&amp;rsquo;s declarative syntax.  As such I&amp;rsquo;m going to spend the rest of this piece focusing on the 2 argument syntax, where the above example would look like what we have below.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;//declare without the className argument
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;
require([&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;dojo/_base/declare&amp;#34;&lt;/span&gt;], &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(declare) {

  &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; Messenger &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; declare(&lt;span style=&#34;color:#ff79c6&#34;&gt;null&lt;/span&gt;, {
    message&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;hello world&amp;#34;&lt;/span&gt;,
    sendMessage&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;() {
        console.log(message);
    }
  });
  &lt;span style=&#34;color:#6272a4&#34;&gt;//since our class was created locally, we can access it here
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; messenger &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; Messenger();
  messenger.sendMessage();

  &lt;span style=&#34;color:#6272a4&#34;&gt;//If we need access our class in other places, we can return it
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#6272a4&#34;&gt;//from a module and then load it as a dependency where needed
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So what is this simple example actually doing?  declare takes the object that you pass and adds it to the prototype chain of your class.  It&amp;rsquo;s important to understand that properties on the prototype are shared between all objects based on that class.  This is perfect for functions, as they only need to be created once.  It also works well for primitive values, since if we rewrite them the values will be added to the object itself rather than the prototype.  Putting properties on the prototype can lead to unexpected behavior when dealing with arrays and more complex objects though.  So its important to understand how the prototype chain works.  For example, the code below produces unexpected output since the messages array is shared between all Messengers.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;require([&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;dojo/_base/declare&amp;#34;&lt;/span&gt;], &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(declare) {

  &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; Messenger &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; declare(&lt;span style=&#34;color:#ff79c6&#34;&gt;null&lt;/span&gt;, {
    messages&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; [&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;hello&amp;#34;&lt;/span&gt;,&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;world&amp;#34;&lt;/span&gt;],
    sendMessages&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;() {
        console.log(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.messages);
    }
  });
  &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; messenger &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; Messenger();
  &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; messenger2 &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; Messenger();

  &lt;span style=&#34;color:#6272a4&#34;&gt;//change the messages array on messenger
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;  messenger.messages.push(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;extra value&amp;#34;&lt;/span&gt;)
  &lt;span style=&#34;color:#6272a4&#34;&gt;//and the change has populated to all instances of Messages
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;  messenger2.sendMessage();
  &lt;span style=&#34;color:#6272a4&#34;&gt;//logs [&amp;#34;hello&amp;#34;, &amp;#34;world&amp;#34;, &amp;#34;extra value&amp;#34;]
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Fortunately Dojo provides an easy way to get around this issue with the special constructor property.  If you define the constructor property of your object as a function, dojo treats that property as the constructor for your class and runs it when instantiating your class.  This allows you to have local properties, and only share properties that should be shared.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;//Constructor example
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;
require([&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;dojo/_base/declare&amp;#34;&lt;/span&gt;], &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(declare) {

  &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; Messenger &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; declare(&lt;span style=&#34;color:#ff79c6&#34;&gt;null&lt;/span&gt;, {
    constructor&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;() {
      &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.messages &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; [&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;hello&amp;#34;&lt;/span&gt;,&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;world&amp;#34;&lt;/span&gt;]
    },
    sendMessages&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;() {
        console.log(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.messages);
    }
  });

  &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; messenger &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; Messenger();
  &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; messenger2 &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; Messenger();
  &lt;span style=&#34;color:#6272a4&#34;&gt;//change the messages array on messenger
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;  messenger.messages.push(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;extra value&amp;#34;&lt;/span&gt;)
  messenger.sendMessage(); &lt;span style=&#34;color:#6272a4&#34;&gt;//logs [&amp;#34;hello&amp;#34;,&amp;#34;world&amp;#34;,&amp;#34;extra value&amp;#34;]
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#6272a4&#34;&gt;//and the change has not populated to other instances of Messages
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;  messenger2.sendMessage(); &lt;span style=&#34;color:#6272a4&#34;&gt;//logs [&amp;#34;hello&amp;#34;,&amp;#34;world&amp;#34;]
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Dojo also provides a special helper function to allow you to define arbitrary properties on a member of the class when an object is created.  You can use code like this to accept object arguments that you can map to properties.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;//safeMixin example
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; TestObject &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; declare(&lt;span style=&#34;color:#ff79c6&#34;&gt;null&lt;/span&gt;, {
  val&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;default&amp;#34;&lt;/span&gt;,
  constructor&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;() {
    &lt;span style=&#34;color:#6272a4&#34;&gt;//make the constructor arguments a mixin
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    declare.safeMixin(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;,args);
  }
})

&lt;span style=&#34;color:#6272a4&#34;&gt;//then we can stick with the default value
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; test &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; TestObject();
&lt;span style=&#34;color:#6272a4&#34;&gt;//or come up with our own
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; spicyTest &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; TestObject({val&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;spicy&amp;#34;&lt;/span&gt;});

alert(spicyTest.val) &lt;span style=&#34;color:#6272a4&#34;&gt;//&amp;#34;spicy&amp;#34;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;inheritance&#34;&gt;Inheritance&lt;/h4&gt;
&lt;p&gt;declare also provides a flexible inheritance option.  In the examples above, we created a class without any inheritance by passing null as the superClass argument.  But we can also specify a class as a superclass.  For instance to create a new messenger that alerts your message instead of logging them, you could inherit the existing Messenger class like the example below.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;//Basic Inheritance
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; AlertMessenger &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; declare(Messenger, {
    sendMessage&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;() {
      alert(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.messages)
    }
  });
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; alerter &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; AlertMessenger();
alerter.sendMessage(); &lt;span style=&#34;color:#6272a4&#34;&gt;//alerts the message
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In this example, AlertMessenger inherits the constructor property from Messenger, but overrides the sendMessage function.  So we change the functionality in a classical OO way.&lt;/p&gt;
&lt;p&gt;One nice feature of Dojo&amp;rsquo;s OO implementation is that it is easy to make calls up the prototype change even when we are overriding functions.  So for instance if we wanted our AlertMessenger class to send an alert while still logging the message in the console, we could use &lt;code&gt;this.inherited&lt;/code&gt; to make it happen.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;//this.inherited Example
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; AlertMessenger &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; declare(Messenger, {
    sendMessage&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;() {
      alert(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.messages);
      &lt;span style=&#34;color:#6272a4&#34;&gt;//calls up the prototype chain to Messenger&amp;#39;s sendMessage function
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;      &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.inherited(arguments);
    }
  });
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; alerter &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; AlertMessenger();
alerter.sendMessage(); &lt;span style=&#34;color:#6272a4&#34;&gt;//alerts and logs the message
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So we still have access to overriden functions if used judiciously. Also, each constructor will be executed along the prototype chain, so there is no need to use &lt;code&gt;this.inherited&lt;/code&gt; in a constructor context.&lt;/p&gt;
&lt;h4 id=&#34;mixins&#34;&gt;Mixins&lt;/h4&gt;
&lt;p&gt;But we&amp;rsquo;re not limited to a single inheritance instance.  We can still do more.  We can also pass an array of classes to the className argument, allowing us to inherit from multiple types at once. The first argument is the base of the prototype chain, and its extended from there, with the additional class properties being mixed in.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;//Multi-Inheritance Example
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; Lion &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; declare( &lt;span style=&#34;color:#ff79c6&#34;&gt;null&lt;/span&gt;, {
  head&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;lion&amp;#34;&lt;/span&gt;,
  body&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;lion&amp;#34;&lt;/span&gt;,
  legs&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;lion&amp;#34;&lt;/span&gt;
});

&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; Bird &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; declare(&lt;span style=&#34;color:#ff79c6&#34;&gt;null&lt;/span&gt;, {
  head&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;bird&amp;#34;&lt;/span&gt;,
  wings&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;bird&amp;#34;&lt;/span&gt;
});

&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; Human &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; declare (&lt;span style=&#34;color:#ff79c6&#34;&gt;null&lt;/span&gt;, {
  head&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;human&amp;#34;&lt;/span&gt;
});

&lt;span style=&#34;color:#6272a4&#34;&gt;//Sphinx is declared with 3 mixins
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;//lion is first, then bird, then human
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; Sphinx &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; declare([Lion,Bird,Human],{
  &lt;span style=&#34;color:#6272a4&#34;&gt;//head gets overriden by human last, wings body and legs are never overriden and stay with their first set values
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;
  aboutMe&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;() {
     alert(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;I have the head of a &amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.head &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt;
           &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;, the wings of a &amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.wings &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt;
           &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;, and the body of a &amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.body);
  }

  });

&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; sphinx &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; Sphinx();

sphinx.aboutMe(); &lt;span style=&#34;color:#6272a4&#34;&gt;//I have the head of a human, the wings of a bird, and the body of a lion
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;when-should-i-use-dojo_basedeclare&#34;&gt;When should I use dojo/_base/declare&lt;/h2&gt;
&lt;p&gt;declare seems like a great choice for creating reusable objects, and allows for either a classical inheritance style or a more flexible mixin style.  Its a bit of overkill for simple or one off objects, but for defining the structure of a complex model, it seems like a great fit.&lt;/p&gt;
&lt;p&gt;Personally I&amp;rsquo;m going to avoid the className syntax unless I find a use for it that I currently don&amp;rsquo;t see.  It seems to be a legacy option that is completely at odds with the rest of Dojo&amp;rsquo;s avoidance of global variables.  The 2 argument syntax on the other hand, seems like a great choice for creating maintainable and reusable classes.&lt;/p&gt;
&lt;p&gt;declare should be especially useful for programmers who want to implement a classical inheritance structure in JS.  It makes the syntax quick and straightforward.  The only gotcha I see is the need to be aware of how the prototype chain works under the covers so that there&amp;rsquo;s no being burned by unexpected sharing of changes.&lt;/p&gt;
&lt;h3 id=&#34;more-resources&#34;&gt;More Resources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://dojotoolkit.org/documentation/tutorials/1.9/declare/&#34;&gt;Official Dojo tutorial on dojo/_base/declare&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://dojotoolkit.org/reference-guide/1.9/dojo/_base/declare.html&#34;&gt;Dojo docs on dojo/_base/declare&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://benmccormick.org/blog/2013/01/12/javascript-explained-object-oriented-javascript/&#34;&gt;JS Explained: Object Oriented Javascript&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;other-modern-dojo-posts&#34;&gt;Other Modern Dojo Posts&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://benmccormick.org/blog/2013/11/13/modern-dojo-dojo-query/&#34;&gt;Exploring dojo/query&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;footnotes&#34;&gt;&lt;ol&gt;
    &lt;li class=&#34;footnote&#34; id=&#34;fn:1&#34;&gt;
        &lt;p&gt;
        I&#39;m not a fan of the dojo convention of having optional arguments be first in some cases.  It seems very strange that arguments might &#34;shift&#34; and not line up as expected.  I can understand in this case not wanting to have a small string parameter after a potentially large object listing the class properties, but it still makes for a confusingly inconsistent API.
        &lt;a href=&#34;#fnref:1&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
&lt;/ol&gt;&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Modern Dojo: Exploring query</title>
      <link>https://benmccormick.org/2013/11/13/181500.html</link>
      <pubDate>Wed, 13 Nov 2013 19:15:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2013/11/13/181500.html</guid>
      <description>&lt;p&gt;It appears I&amp;rsquo;m going to be spending a significant amount of time working with &lt;a href=&#34;http://dojotoolkit.org/&#34;&gt;the Dojo toolkit&lt;/a&gt; for my next project at work, so I&amp;rsquo;ve spent some time over the last few days trying to familiarize myself with the library.  Its quickly become apparent that there are a few challenges with learning Dojo at the pace I wanted.  First, Dojo is built as a lightweight core with many small modules of functionality available as components.  It&amp;rsquo;s effectively completely modularized in a way that no other framework really is (though jQuery appears to be moving in that direction as well).  As such, learning it is a bit decentralized.  Second, Dojo, which has existed since 2005, made a big transition back in 2011 to move to an AMD format for managing its modular components.  This resulted in a significant change in basic syntax.  Since this change happened after jQuery&amp;rsquo;s rise (which led to a significant drop in Dojo usage), it seems many examples on the web still use the old syntax, and I haven&amp;rsquo;t seen any print resources published since the change.  As a result, the resources for learning modern Dojo seem somewhat piecemeal beyond the toolkit&amp;rsquo;s website.&lt;/p&gt;
&lt;p&gt;That being the case, I&amp;rsquo;ve decided to explore Dojo&amp;rsquo;s primary modules on a case by case basis and document what I&amp;rsquo;ve learned here.  Hopefully this can be a helpful modern reference to others who are learning.  I&amp;rsquo;m going to start by exploring dojo/query, one of the primary Dojo modules, which provides jQuery selector style functions for Dojo users.&lt;/p&gt;
&lt;h2 id=&#34;what-is-dojoquery-for&#34;&gt;What is dojo/query for?&lt;/h2&gt;
&lt;p&gt;dojo/query is the Dojo module for dom selection.  The core module provides basic CSS selection capability, with the ability to use CSS3 style selectors if needed.  It can be extended using other modules to provide more advanced DOM traversal and manipulation functionality, effectively matching jQuery&amp;rsquo;s feature set in that area.&lt;/p&gt;
&lt;h2 id=&#34;how-do-you-use-dojoquery&#34;&gt;How do you use dojo/query?&lt;/h2&gt;
&lt;p&gt;To use dojo/query, you first need to require the module, using an AMD style require or define call.  You can then call query (or whatever you&amp;rsquo;ve aliased it to), and pass it a CSS style selector.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;//Basic query example
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;
require([&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;dojo/query&amp;#34;&lt;/span&gt;], &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(query){
    &lt;span style=&#34;color:#6272a4&#34;&gt;//select all elements with class special
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; elementList &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; query(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;.special&amp;#34;&lt;/span&gt;);

    &lt;span style=&#34;color:#6272a4&#34;&gt;//you can also add an optional second parameter to search
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#6272a4&#34;&gt;//under a single DOM element,rather than the whole DOM
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; parentNode &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;document&lt;/span&gt;.getElementById(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;parent&amp;#34;&lt;/span&gt;);
    elementList &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; query(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;.children&amp;#34;&lt;/span&gt;,parentNode);
});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The query function returns a dojo/NodeList object.  This is a basic array-like wrapper object, similar to a jQuery object.  By default it contains some basic array manipulation functions, but you can also extend it with plugin modules for dom manipulation, dom traversal, and other functions.  In fact you can even write your own extensions to the object.  These extensions are loaded in as additional AMD modules. For instance, we can load dojo/NodeList-dom to extend NodeList with some basic DOM functionality&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;//Extending NodeList
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;
require([&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;dojo/query&amp;#34;&lt;/span&gt;,&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;dojo/NodeList-dom&amp;#34;&lt;/span&gt;], &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(query){
    &lt;span style=&#34;color:#6272a4&#34;&gt;//add a btn class to all button elements
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    query(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;button&amp;#34;&lt;/span&gt;).addClass(btn);
});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In that simple example, the &lt;code&gt;addClass&lt;/code&gt; method was added as an extension to the NodeList type by the NodeList-dom module.  So adding that module brought extra functionality.  Its relatively simple to add custom functionality in this way.  An example from the Dojo docs looks like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;//Dojo extension example
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;
&lt;span style=&#34;color:#6272a4&#34;&gt;//definition (in myapp/NodeList-custom.js)
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;define([&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;dojo/_base/lang&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;dojo/query&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;dojo/NodeList-dom&amp;#34;&lt;/span&gt;], &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(lang, query){
  lang.extend(query.NodeList, {
    makeRed&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(){
      &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.style({ color&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;red&amp;#34;&lt;/span&gt; });
      &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;;
    }
  });
});

&lt;span style=&#34;color:#6272a4&#34;&gt;//usage (in another file)
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;
require([&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;dojo/query&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;myapp/NodeList-custom&amp;#34;&lt;/span&gt;], &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(query){
  query(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;.greenText&amp;#34;&lt;/span&gt;).makeRed();
});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is great for modularizing common patterns and functionality, and is a core Dojo concept, not just a dojo/query feature.&lt;/p&gt;
&lt;h2 id=&#34;how-does-dojoquery-perform&#34;&gt;How does dojo/query perform?&lt;/h2&gt;
&lt;p&gt;I was curious about how dojo/query performance stacked up to jQuery.  So I set up some performance tests on &lt;a href=&#34;http://jsperf.com/&#34;&gt;jsPerf&lt;/a&gt; to take a look.  I compared Dojo to jQuery across a few common and simple selection and manipulation operations.  The results were informative.&lt;/p&gt;
&lt;p&gt;You can see the results here for&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://jsperf.com/dojo-query-vs-jquery-selectors&#34;&gt;ID selection&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://jsperf.com/dojo-query-vs-jquery-selectors-for-class-search&#34;&gt;Class selection&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://jsperf.com/dojo-query-vs-jquery-selectors-for-class-manipulation&#34;&gt;DOM manipulation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The results varied a bit from platform to platform, but a few things stood out.&lt;/p&gt;
&lt;h4 id=&#34;when-selecting-on-ids-dont-use-dojoquery&#34;&gt;When selecting on IDs, don&amp;rsquo;t use dojo/query&lt;/h4&gt;
&lt;p&gt;For the basic ID selection tests, dojo/query was blown away by almost everything. It is very very slow to handle it.  I was initially bothered by this, until I added the dojo/dom test.  dojo/dom&amp;rsquo;s byID function is the &amp;ldquo;dojo way&amp;rdquo; of selecting an element by ID.&lt;/p&gt;
&lt;p&gt;dom.byId appears to be a thin wrapper around the native API, with near native performance everywhere (and confusingly, better than native performance on IE11).  dojo/query meanwhile, lags way behind, literally 100x slower than a native query on Chrome 31.  You can still integrate with dojo/NodeList to get dojo/query&amp;rsquo;s chaining functionality&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;//Method chaining with search by ID
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;
require([&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;dojo/query&amp;#34;&lt;/span&gt;,&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;dojo/dom&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;dojo/NodeList-dom&amp;#34;&lt;/span&gt;], &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(query,dom){

    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; list &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; query.NodeList();
    list.push(dom.byId(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;menu&amp;#34;&lt;/span&gt;));

    list.addClass(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;sidebar&amp;#34;&lt;/span&gt;).onclick(&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(e) {
        alert (&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;this is the menu&amp;#34;&lt;/span&gt;);
    })
});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;for-simple-things-operations-you-cant-beat-native-selectors&#34;&gt;For simple things operations, you can&amp;rsquo;t beat native selectors&lt;/h4&gt;
&lt;p&gt;On the basic tests, the native selectors blow away the library results, with little downside.  When you&amp;rsquo;re simply trying to access an element and, for instance, change its inner HTML, native selectors will scale much better.&lt;/p&gt;
&lt;p&gt;However, the situation begins to become more complicated when more complex queries are involved.  My manipulation example is still a relatively simple example, but the trade-offs start becoming a lot more substantial very rapidly.  For the manipulation example, native code requires significantly more code.  The simplest method of doing things is not supported on IE9, and requires you to understand the distinction between an HTMLCollection and a normal Javascript array.  A solution that supports IE9 and handles other edge cases involves even more code, and performs in the same range as Dojo and jQuery.&lt;/p&gt;
&lt;h4 id=&#34;dojoquery-seems-to-lag-behind-jquery-in-performance-but-its-in-the-ballpark&#34;&gt;dojo/query seems to lag behind jQuery in performance, but its in the ballpark&lt;/h4&gt;
&lt;p&gt;dojo/query was consistently outperformed by jQuery in the testing that I did.  But while the gap between native selectors and library versions is very wide, the dojo/jQuery divide seems to be on the order of a 2-4x increase in speed on basic operations.  Thats significant, but hardly damning. If selector performance is your primary criteria for choosing a library, jQuery should be your pick.  But Dojo is competitive enough here, that it doesn&amp;rsquo;t seem disqualified for use if you have other reasons for doing so.&lt;/p&gt;
&lt;h2 id=&#34;when-should-i-use-dojoquery&#34;&gt;When should I use dojo/query?&lt;/h2&gt;
&lt;p&gt;To sum it all up, it looks like the query library is a great choice for providing jQuery selector style functionality for Dojo users.  It&amp;rsquo;s small, lightweight, and allows you to load only the things you need to get the job done.  If you only are looking for this type of selector functionality, a custom built jQuery package might be a better fit. But if you&amp;rsquo;re already using Dojo, dojo/query will get the job done very well.  Just don&amp;rsquo;t use it to search on id&amp;rsquo;s.  Use dojo/dom or native selectors instead.&lt;/p&gt;
&lt;h2 id=&#34;more-resources&#34;&gt;More Resources&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://dojotoolkit.org/documentation/tutorials/1.9/using_query/&#34;&gt;Official Dojo tutorial on dojo/query&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://dojotoolkit.org/reference-guide/1.9/dojo/query.html&#34;&gt;Dojo docs on dojo/query&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://dojotoolkit.org/reference-guide/1.9/dojo/NodeList.html&#34;&gt;Dojo docs on NodeList&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>BlendConf 2013: Takeaways From A Very Human Tech Conference</title>
      <link>https://benmccormick.org/2013/09/10/150000.html</link>
      <pubDate>Tue, 10 Sep 2013 16:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2013/09/10/150000.html</guid>
      <description>&lt;p&gt;After 3 great days at &lt;a href=&#34;http://blendconf.com/&#34;&gt;Blendconf&lt;/a&gt;, my brain is pretty overloaded with cool ideas. One of the cool things about the conference was seeing certain themes emerge across different sessions.  Here are three of my takeaways from a great weekend.&lt;/p&gt;
&lt;h2 id=&#34;modular-web-development&#34;&gt;Modular Web Development&lt;/h2&gt;
&lt;p&gt;The biggest technical theme that I noticed in the different sessions I attended was a focus on modular design in JS and CSS. &lt;a href=&#34;https://twitter.com/shayhowe&#34;&gt;Shay Howe&lt;/a&gt; gave a great workshop where he encouraged us to view CSS at a component level rather than at a page level.  That was followed by talks from &lt;a href=&#34;https://twitter.com/jina&#34;&gt;Jina Bolton&lt;/a&gt; and &lt;a href=&#34;http://wiseheartdesign.com/&#34;&gt;John Long&lt;/a&gt;, who reinforced the patterns that Shay had advocated for, and also showed how they could be implemented with preprocessors like SASS. &lt;a href=&#34;https://twitter.com/vernonk&#34;&gt;Vernon Kesner&lt;/a&gt; also gave a great talk on using requireJS for modular Javascript.  That&amp;rsquo;s a relevant topic to me, since I&amp;rsquo;ve spent the last 2 months working to convert a large codebase to AMD modules, and Vernon did a great job explaining the motivation for modular JS.&lt;/p&gt;
&lt;h2 id=&#34;design-and-development-should-not-be-separate-processes&#34;&gt;Design and Development should not be separate processes&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Design is how it works. &amp;ndash; Steve Jobs&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;One of the real key points that multiple speakers hammered home was the importance of having tightly bound design and development.  &lt;a href=&#34;https://twitter.com/cameronmoll&#34;&gt;Cameron Moll&lt;/a&gt; talked about the importance of really understanding and being true to the things that you&amp;rsquo;re creating.  &lt;a href=&#34;https://twitter.com/imathis&#34;&gt;Brandon Mathis&lt;/a&gt; argued convincingly that its important for designers to know their material.&lt;/p&gt;
&lt;h2 id=&#34;leave-things-better-than-you-found-them&#34;&gt;Leave Things Better Than You Found Them&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Aspire to change your world in some small but significant way &amp;ndash;Cameron Moll&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I feel like this final point in some ways sums up what BlendConf is all about.  Its the result of &lt;a href=&#34;https://twitter.com/bermonpainter&#34;&gt;one man&lt;/a&gt; thinking about how cool it would be to have a big-time tech conference in Charlotte and then going and making it happen, then going out and finding speakers who set a vision of a tech career that was about more than money.  &lt;a href=&#34;https://twitter.com/carlsmith&#34;&gt;Carl Smith&lt;/a&gt; talked about his quest to find a more humane company structure.  &lt;a href=&#34;https://twitter.com/ashedryden&#34;&gt;Ashe Dryden&lt;/a&gt; encouraged us to look for the people who are being excluded from tech culture and find ways to bring them in. &lt;a href=&#34;https://twitter.com/greggyb&#34;&gt;Greg Baugues&lt;/a&gt; told us about how he&amp;rsquo;d worked through his bipolar disorder at least partially through the support of his coworkers and friends, while also showing that many people still don&amp;rsquo;t receive that support. Cameron Moll set the goal as &amp;ldquo;aspiring to change the world in a small but significant way.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Blendconf was the first major tech conference I&amp;rsquo;ve attended.  I wasn&amp;rsquo;t totally sure what to expect, but it defied whatever expectations I did have with it&amp;rsquo;s humanity. I&amp;rsquo;m excited to see that it is becoming an annual conference, and can&amp;rsquo;t wait to see where it goes from here.&lt;/p&gt;
&lt;h2 id=&#34;a-great-summary-from-twitter&#34;&gt;A Great Summary From Twitter&lt;/h2&gt;
&lt;blockquote class=&#34;twitter-tweet&#34;&gt;&lt;p&gt;The best part of &lt;a
href=&#34;https://twitter.com/blendconf&#34;&gt;@blendconf&lt;/a&gt; wasn’t the device
policy or the talks, it was the uniformly awesome love and energy from
everyone there.&lt;/p&gt;&amp;mdash; Tim Cheadle (@timcheadle) &lt;a
href=&#34;https://twitter.com/timcheadle/statuses/376491690791817217&#34;&gt;September
7, 2013&lt;/a&gt;&lt;/blockquote&gt;
</description>
    </item>
    
    <item>
      <title>Searching for the perfect reading device:  My Nexus 7 (2013) Review</title>
      <link>https://benmccormick.org/2013/08/16/070000.html</link>
      <pubDate>Fri, 16 Aug 2013 08:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2013/08/16/070000.html</guid>
      <description>&lt;p&gt;Since Amazon announced its Kindle platform back in 2007, I have read books on a variety of different devices.  I&amp;rsquo;ve owned and used two different Kindle devices and experimented with the rest.  I&amp;rsquo;ve read on my smartphones, iPad, laptop, and traditional paper books. There are great things about each, but there are also aspects of all of them that drive me crazy.&lt;/p&gt;
&lt;p&gt;When the new Nexus 7 was announced last month, it seemed like the type of device I was waiting for: powerful, light, and affordable. Most importantly, it included a screen that would be easy on the eyes.&lt;/p&gt;
&lt;h2 id=&#34;the-problem-with-the-kindle&#34;&gt;The Problem with the Kindle&lt;/h2&gt;
&lt;p&gt;Up until now, I&amp;rsquo;ve mostly used Kindles for long form reading.  Their e-ink screens are fantastic,the experience is seamless when reading Amazon content , and they&amp;rsquo;re light and easy to hold as a small paperback.  The problem is, while I love reading, a lot of the content I was interested in, including blogs, the Bible, online news, and magazines, was difficult or impossible to access on a traditional Kindle.  In addition, my Kindle often wasn&amp;rsquo;t able to cope with the diagrams and code snippets common in the more technical books I read.&lt;/p&gt;
&lt;p&gt;As a result, my Kindle often ended up neglected, and I used my iPhone or laptop instead.  Kindles are fantastic reading hardware, but their lack of integration with non Amazon store content cripples their usefulness.  I think Amazon&amp;rsquo;s best play here would be to make a deal with a service like Pocket or Instapaper &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; rel=&#34;footnote&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; for deep integration that goes beyond the almost unusable &amp;ldquo;send document to Kindle&amp;rdquo; integration that Instapaper currently provides&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; rel=&#34;footnote&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;.  That would go a long way to making it a viable multi-purpose reading device.&lt;/p&gt;
&lt;p&gt;As for the Kindle Fire line, they serve as a step in the right direction, but have consistently been panned for laggy performance and an interface that is effectively a store front.  They still might be a valid contender though, except for the growth of other options that don&amp;rsquo;t share those problems.&lt;/p&gt;
&lt;h2 id=&#34;why-not-an-ipad&#34;&gt;Why not an iPad?&lt;/h2&gt;
&lt;p&gt;The other serious contender for the title of &amp;ldquo;best reading device&amp;rdquo; is the iPad.  Since it first came out in 2010, it has quickly become the most popular choice for multimedia consumption on a midsize (7-11 inch) screen. It has arguably the best hardware, and inarguably the best selection of third party apps and integrations.  The question then becomes, &amp;ldquo;Which iPad?&amp;rdquo;&lt;/p&gt;
&lt;p&gt;The &amp;ldquo;original iPad&amp;rdquo; line, now on its fourth generation, boasts a large ten inch screen- one of the nicest screens you can find on a mobile device. It also hosts three and a half years-worth of apps designed specifically for the iPad&amp;rsquo;s size and form.  It is by almost all accounts the best multipurpose tablet that money can buy.  As a reading device, though, it leaves much to be desired.  At 1.44 lbs, it&amp;rsquo;s heavy and awkward to hold in one hand. It&amp;rsquo;s also expensive: $200-$400 greater than other reading devices.  These factors can easily be overlooked relative to the versatility and utility of the iPad as a productivity and media-consumption device, but they make it difficult to recommend as a pure reader.&lt;/p&gt;
&lt;p&gt;The iPad mini, on the other hand, is almost the perfect shape and size for a reader.  It is the lightest high-end tablet on the market, and also feels like much more of a premium device than the Nexus or the Kindle when you hold one in your hand.  It comes at a reasonable cost ($170 less than the &amp;ldquo;regular&amp;rdquo; iPad), and like the Retina iPad, it comes with the full support of the Apple ecosystem. The iPad mini is its older sibling&amp;rsquo;s only truly valid competitor for &amp;ldquo;best multipurpose tablet&amp;rdquo;, and a completely valid choice as a reading device at that.&lt;/p&gt;
&lt;p&gt;On the other hand, the iPad mini also has a screen that is completely blown away by all of its competitors.  Compared to any of the other devices mentioned here, its text looks pixelated and less crisp, as you can see in this comparison from &lt;a href=&#34;http://arstechnica.com/gadgets/2013/07/the-2013-nexus-7-review-meet-the-new-standard-for-android-tablets/&#34;&gt;Ars Technica&amp;rsquo;s Nexus 7 review&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;textcomp.jpg&#34; alt=&#34;Comparing the text&#34;&gt;&lt;/p&gt;
&lt;p&gt;For many uses this is not a big deal, but when reading longform text, I find that the display resolution really makes a difference in how long I&amp;rsquo;m able to read comfortably.  When I looked at the Mini in my local Apple store, iBooks&#39; text was significantly less crisp than it was on the other devices.  Combined with the extra cost relative to a Kindle or Nexus 7, it becomes difficult to justify recommending an iPad Mini as a reading-focused device.&lt;/p&gt;
&lt;h2 id=&#34;enter-the-nexus-7&#34;&gt;Enter the Nexus 7&lt;/h2&gt;
&lt;p&gt;The new Nexus 7 manages to avoid many of the tradeoffs hindering the other devices.  It has a top of the line screen at a price point directly in between the Kindle Paperwhite and the iPad Mini.  It also remains easy to hold, with a smaller (though slightly heavier) frame than the Mini. And since it is a full Android tablet, it comes equipped with a real web browser and integrations with all the most prominent reading services &lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; rel=&#34;footnote&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;.  That&amp;rsquo;s the Nexus 7&amp;rsquo;s promise, but is it able to live up to it?&lt;/p&gt;
&lt;h2 id=&#34;a-beautiful-screen&#34;&gt;A beautiful screen&lt;/h2&gt;
&lt;p&gt;The first thing you notice when you see a Nexus 7 is the screen. It&amp;rsquo;s a premium component set inside an otherwise solid but unremarkable slab.  The icons on the home screen are crisp and detailed, and the text is clear.  It&amp;rsquo;s a screen that practically begs you to read.&lt;/p&gt;
&lt;p&gt;The only downside of the screen is that not every device has one yet.  As a result, web sites and non-optimized apps can appear blurry and pixelated.  The images and toolbars in my preferred Bible app, for instance, appear out of focus, although the text itself is still crisp and readable.  This is the price of progress though, and something that Apple users have had to deal with each time a device has transitioned to Retina.  Android&amp;rsquo;s fragmentation will make the transition slower,  but its a problem that will be mitigated over time as more apps are targeted at newer devices with high resolutions.&lt;/p&gt;
&lt;h2 id=&#34;easy-to-hold&#34;&gt;Easy to hold&lt;/h2&gt;
&lt;p&gt;When I bought the Nexus 7, I was nervous about how the device would feel.  Unlike iPads, which you can touch and handle in Apple stores, it&amp;rsquo;s difficult to know how a Google product will feel in your hands before you buy one.  My local Best Buy had a single test unit, and it was anchored to the display table with a 6&amp;quot; plastic cord that weighed about as much as the device itself &lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; rel=&#34;footnote&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;.  I couldn&amp;rsquo;t find any other way to actually touch a Nexus 7 without purchasing, so I decided to purchase one before I went on a vacation and give it a week to prove itself.&lt;/p&gt;
&lt;p&gt;In the end I was satisfied, if not quite delighted, by the devices feel.  It feels sturdy in the hands, and definitely falls into the &amp;ldquo;book&amp;rdquo; size range. On the other hand, the Nexus 7 is both smaller and heavier than an iPad mini, giving it some unwanted heft.  This seems like an unavoidable consequences of cramming a Retina-class screen into a 7&amp;quot; tablet while maintaining reasonable battery life.  But it does mean that it can&amp;rsquo;t match the paperback feel of the Kindle or the &amp;ldquo;pleasant to hold&amp;rdquo; sensation of the iPad Mini.  The Nexus 7 makes you think a bit more about it than those two devices, which is probably the biggest knock on it as a reader.  It&amp;rsquo;s not too heavy to hold in one hand, but it may feel a bit awkward doing so.  I usually end up using two hands if I&amp;rsquo;m sitting down to read, but will hold it with one hand if I&amp;rsquo;m carrying it around.&lt;/p&gt;
&lt;h2 id=&#34;what-about-the-apps&#34;&gt;What about the apps?&lt;/h2&gt;
&lt;p&gt;The app selection was my second biggest concern when considering the Nexus 7.  As a previous owner of one of the original Windows Phones, I know what it&amp;rsquo;s like to work with a platform that doesn&amp;rsquo;t get full support from developers.  If you love the OS you can still have a good experience, but your choices will be limited and you may not be able to make some things work.  Android tablets in 2013 aren&amp;rsquo;t quite where Windows Phone was in 2010, but there is a big drop in the quality and consistency of tablet apps from the iPad to an Android tablet.  When it comes to reading, however, this seems to be a manageable issue.&lt;/p&gt;
&lt;p&gt;Android has high quality tablet apps for book reading, RSS, and Read-It-Later services.  The Kindle app is solid, though it&amp;rsquo;s missing some features from the iOS app like the X-ray option and the ability to change fonts.  &lt;a href=&#34;http://twentyfivesquares.com/press/&#34;&gt;Press&lt;/a&gt; is as good as any RSS client I&amp;rsquo;ve tried on iOS or the desktop.  &lt;a href=&#34;http://www.instapaper.com/&#34;&gt;Instapaper&lt;/a&gt; is surprisingly nice on Android, given &lt;a href=&#34;http://www.marco.org/&#34;&gt;Marco Arment&amp;rsquo;s&lt;/a&gt; &lt;a href=&#34;http://www.marco.org/2013/08/13/google-blindness&#34;&gt;well documented skepticism&lt;/a&gt; toward Android.  There are other solid options for those using other services, including apps for Pocket, Nook, and Feedly.&lt;/p&gt;
&lt;h2 id=&#34;the-verdict&#34;&gt;The Verdict&lt;/h2&gt;
&lt;p&gt;Overall I&amp;rsquo;ve been incredibly pleased with the Nexus 7 so far.  I think it makes the right tradeoffs for a reading device.  It adds a little extra heft in exchange for a brilliant screen at an affordable cost, in a package that is still smaller than many paperbacks.  It might not please somebody looking for a multipurpose media tablet: it&amp;rsquo;s still missing popular iOS apps like Amazon Instant Video and Tweetbot&lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34; rel=&#34;footnote&#34;&gt;5&lt;/a&gt;&lt;/sup&gt; (and even when apps do exist they&amp;rsquo;re &lt;a href=&#34;http://www.webpronews.com/android-is-still-missing-top-ipad-apps-2013-08&#34;&gt;often not optimized for tablets&lt;/a&gt;).  But if you don&amp;rsquo;t need that functionality, there is a lot here to love.  As a multi-source reading device, the Nexus 7 is king.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Update June 2014: After almost a year with the Nexus 7, I stand by my analysis of the tradeoffs involved with different devices.  But I&amp;rsquo;ve found that the ones the Nexus 7 make bother me more than I expected.  It&amp;rsquo;s ended up feeling like an impractical device for me.  Because it&amp;rsquo;s battery life doesn&amp;rsquo;t match something like the kindle, I have to worry about charging it.  But because it doesn&amp;rsquo;t have the general utility of the iPad (or more importantly my iPhone), I end up neglecting it.  The lack of a decent twitter app, and the lack of polish on most non-Google apps makes it a tough sell when faced with the option of doing something on the Nexus vs doing it on my phone or laptop.  I still think the Nexus 7 is a great device.  But it has not met my needs as well as I expected&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;a target=&#34;_blank&#34; href=&#34;http://www.amazon.com/s/?_encoding=UTF8&amp;camp=1789&amp;creative=390957&amp;field-keywords=Nexus%207&amp;linkCode=ur2&amp;rh=i%3Aaps%2Ck%3ANexus%207&amp;tag=benmccormicko-20&amp;url=search-alias%3Daps&amp;linkId=IQG4KEHRXYATOHXG&#34;&gt;Get The Nexus 7 (Amazon Affiliate Link)&lt;/a&gt;&lt;img src=&#34;https://ir-na.amazon-adsystem.com/e/ir?t=benmccormicko-20&amp;l=ur2&amp;o=1&#34; width=&#34;1&#34; height=&#34;1&#34; border=&#34;0&#34; alt=&#34;&#34; style=&#34;border:none !important; margin:0px !important;&#34; /&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;div class=&#34;footnotes&#34;&gt;
&lt;ol&gt;
&lt;li class=&#34;footnote&#34; id=&#34;fn:1&#34;&gt;
&lt;p&gt;
Actually, an Amazon acquisition seems like the perfect out for Pocket, a popular service that completely lacks a business model.
&lt;a href=&#34;#fnref:1&#34; title=&#34;return to article&#34;&gt; ↩
&lt;/a&gt;&lt;/p&gt;
&lt;li class=&#34;footnote&#34; id=&#34;fn:2&#34;&gt;
&lt;p&gt;
To be clear, it&#39;s unusable because Amazon makes it unusable.  There is no way (as far as I can tell) to bulk-delete documents, or delete a document from the device after you finish it.  Instead, you have to go to Amazon.com later and delete documents one at a time. It&#39;s left my Kindle library  littered with old Instapaper articles that I have no interest in reading again.
&lt;a href=&#34;#fnref:2&#34; title=&#34;return to article&#34;&gt; ↩
&lt;/a&gt;&lt;/p&gt;
&lt;li class=&#34;footnote&#34; id=&#34;fn:3&#34;&gt;
&lt;p&gt;
In my case that&#39;s Kindle, Instapaper, Feedbin and Pinboard, but it equally supports Nook, Pocket, Feedly, Delicious and most other popular services.  Of course if all your books are in iBooks then you probably haven&#39;t even made it this far.
&lt;a href=&#34;#fnref:3&#34; title=&#34;return to article&#34;&gt; ↩
&lt;/a&gt;&lt;/p&gt;
&lt;li class=&#34;footnote&#34; id=&#34;fn:4&#34;&gt;
&lt;p&gt;
Best Buy seems to go out of its way to cater to people who don&#39;t actually care if their devices are nice.  They&#39;ve gotten a little better with some of their featured electronic displays. There was a very nice &#34;touch and play&#34; section for Samsung devices.  But it always seems like half the display devices are non-functional, and they&#39;re actively trying to push Windows machines with reasonable specs, cheap plastic casing and trackpads you have to hit with a hammer to get a response.
&lt;a href=&#34;#fnref:4&#34; title=&#34;return to article&#34;&gt; ↩
&lt;/a&gt;&lt;/p&gt;
&lt;li class=&#34;footnote&#34; id=&#34;fn:5&#34;&gt;
&lt;p&gt;
Obviously there are plenty of twitter apps on Android, but I haven&#39;t been able to find one that is anywhere near as nice to use as Tweetbot. That&#39;s obviously a compliment to Tweetbot&#39;s development team, though it does seem to me that there may be some API limits that are hurting the Android apps.  Otherwise, I can&#39;t understand why they seem to universally require 2 taps to follow a link.
&lt;a href=&#34;#fnref:5&#34; title=&#34;return to article&#34;&gt; ↩
&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;/li&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/ol&gt;&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Somewhat Open</title>
      <link>https://benmccormick.org/2013/08/15/111500.html</link>
      <pubDate>Thu, 15 Aug 2013 12:15:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2013/08/15/111500.html</guid>
      <description>&lt;p&gt;&lt;a href=&#34;http://blogs.technet.com/b/microsoft_on_the_issues/archive/2013/08/15/the-limits-of-google-s-openness.aspx&#34;&gt;From Microsoft&amp;rsquo;s official &amp;ldquo;Microsoft on the Issues&amp;rdquo; Blog:&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;It seems to us that Google’s reasons for blocking our app are manufactured so that we can’t give our users the same experience Android and iPhone users are getting. The roadblocks Google has set up are impossible to overcome, and they know it.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It&amp;rsquo;s ok to have an open API, and it&amp;rsquo;s ok to not have an open API so that your competitors can&amp;rsquo;t benefit from your services, but claiming to have an open API and then shutting out users of a competitors platforms on a string of technicalities? That&amp;rsquo;s just a joke.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Book Review: User-Centered Design</title>
      <link>https://benmccormick.org/2013/08/12/101500.html</link>
      <pubDate>Mon, 12 Aug 2013 11:15:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2013/08/12/101500.html</guid>
      <description>&lt;p&gt;User-Centered Design by Travis Lowdermilk is a solid overview of the principles and practices of designing a software project with a focus on your users.  The book does a good job of laying out the basic tools and processes of user-centered design, like usability studies, surveys, and project plans.  It also argues convincingly for the power  of its central points: user focus, preparation, and a structured process.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re looking for a deep dive into design theory, this is probably not a book you want.  Rather than dig into abstract design issues, this book instead acts as a survey of the user-centered design landscape, and points you to resources to go deeper if a particular topic catches your interest.  Lowdermilk also does a good job of pointing out examples of the different principles discussed, though for a stretch of the book he appears to be a bit fixated on a small selection of examples, particularly 53 Inc.&amp;rsquo;s popular iPad app &lt;a href=&#34;https://itunes.apple.com/us/app/paper-by-fiftythree/id506003812?mt=8&#34;&gt;Paper&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;d recommend this book for developers who want to open their minds to design considerations and improve their ability to make usable products.  It particularly seems suited for the engineer who knows technically how to implement features and write good code, but is still figuring out how to write applications that delight users.  I&amp;rsquo;d especially recommend it for team leads or independent developers who are more likely to be able to meet users and be a part of managing requirements.  I think all engineers could benefit from the books emphasis on the users point of view, but the real benefits will come to those who are able to make its suggestions part of the structure of their product workflows.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://www.amazon.com/gp/product/1449359809/ref=as_li_tl?ie=UTF8&amp;camp=1789&amp;creative=390957&amp;creativeASIN=1449359809&amp;linkCode=as2&amp;tag=benmccormicko-20&amp;linkId=5XN7KS7FCBFHZ54O&#34;&gt;Buy User-Centered Design on Amazon (Affiliate Link)&lt;/a&gt;&lt;img src=&#34;http://ir-na.amazon-adsystem.com/e/ir?t=benmccormicko-20&amp;l=as2&amp;o=1&amp;a=1449359809&#34; width=&#34;1&#34; height=&#34;1&#34; border=&#34;0&#34; alt=&#34;&#34; style=&#34;border:none !important; margin:0px !important;&#34; /&gt;&lt;/p&gt;
&lt;p&gt;This review was part of the &lt;a href=&#34;http://oreilly.com/bloggers/&#34;&gt;O&amp;rsquo;Reilly Blogger Program&lt;/a&gt;.  I am not compensated for this review, but did receive a free review copy of the book.  The opinions expressed here are my own.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>RSS Roundup</title>
      <link>https://benmccormick.org/2013/06/29/064000.html</link>
      <pubDate>Sat, 29 Jun 2013 07:40:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2013/06/29/064000.html</guid>
      <description>&lt;p&gt;We&amp;rsquo;re at T-3 days till the Google Reader shutdown, and it seems like the &amp;ldquo;wait and see&amp;rdquo; crowd has made their initial decisions.  As a large crop of companies and products have weighed in, a large and diverse selection of &amp;ldquo;Google Reader replacements&amp;rdquo; have formed.  The groups behind them range from small indie developers (Feedbin, Go Reader) to fallen internet giants looking to reclaim glory (Digg, AOL). The readers themselves seem to fall into a few main categories:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Free cloud service aiming for scale&lt;/li&gt;
&lt;li&gt;Free, paid, or ad-hoc self hosted option&lt;/li&gt;
&lt;li&gt;Former Reader clients allowing standalone RSS or a proprietary sync service&lt;/li&gt;
&lt;li&gt;Paid cloud hosted option&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Lots of others have chimed in with reviews of each of these services over the last few days, but I think that its hard to recommend a specific service universally, since people have different things they&amp;rsquo;re looking for in those services.  So I thought I&amp;rsquo;d take a look at the different categories and see why somebody would use them.&lt;/p&gt;
&lt;h3 id=&#34;free-cloud-based-services&#34;&gt;Free cloud based services&lt;/h3&gt;
&lt;p&gt;It seems like the most popular Reader replacement has been Feedly.  Its one of several options that try to replicate what Reader provided while also maintaining its non-existent price tag.  In doing so, they also inherit the inherent dangers of a product that adds more expense than revenue for each user they gain.  Products like that can seem like an obvious choice for users in the short term, but the results are often &lt;a href=&#34;http://mashable.com/2012/11/16/tweetro-dead-twitter-api/&#34;&gt;less pleasant&lt;/a&gt; in the long term.  Business models built around free products incentivize behaviors in ways that are unrelated to the customers&#39; best interests.  This can eventually cause privacy issues or unwanted restrictions.  &lt;em&gt;They also can go the way of Google Reader, a product that was killed off when the costs were no longer worth the benefits provided.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;However, this group does best meet the expectations of an audience used to the free &amp;ldquo;available anywhere&amp;rdquo; nature of Google Reader, and includes several excellent products.  Feedly clearly has become a major undertaking, and Digg Reader has an elegant minimalistic style. Each has its flaws, but also has a dedicated team behind it that is clearly listening to feedback and determined to succeed.&lt;/p&gt;
&lt;h3 id=&#34;self-hosted-options&#34;&gt;Self Hosted Options&lt;/h3&gt;
&lt;p&gt;There is a certain type of person whose immediate reaction to seeing Google Reader&amp;rsquo;s shutdown was to give up on external services and write their own. If you have tried that then you probably already have very strong opinions on this issue.  If you didn&amp;rsquo;t, the good news is that several of these efforts have produced public open source options.  There are also other options for self-hosting RSS, most notably &lt;a href=&#34;http://www.feedafever.com/&#34;&gt;Fever&lt;/a&gt;, a self hosted app that you can purchase for a 1 time $30 fee and then host yourself. There&amp;rsquo;s also &lt;a href=&#34;http://mattjibson.com/blog/2013/06/26/go-read-open-source-google-reader-clone/&#34;&gt;Go Read&lt;/a&gt;, an open source app whose author is currently hosting it for free on App Engine (with ads soon to come), but also has open-sourced it and made it easy to run on App Engine&amp;rsquo;s free limits.&lt;/p&gt;
&lt;p&gt;In the end, these options will appeal to those who want to control their experience, and especially those who want to tinker.  But for most this will look like a lot of work and expense for unclear benefits.&lt;/p&gt;
&lt;h3 id=&#34;reader-clients&#34;&gt;Reader Clients&lt;/h3&gt;
&lt;p&gt;A huge ecosystem of apps was built up around Google Reader over the past several years.  There are &amp;ldquo;Google Reader&amp;rdquo; apps on every major platform with different styles and features to appeal to a wide variety of users.  Especially on mobile, most users accessed Reader through one of these apps, rather than through the site itself.  Now that Google Reader has removed the sync backbone of their community, these apps have had the opportunity and challenge of reinventing themselves.  Most have adapted one or more of the new services, but some are focusing on local RSS or are developing their own sync service.  &lt;a href=&#34;http://netnewswireapp.com/&#34;&gt;NetNewsWire&lt;/a&gt; in particular seems to be going it alone.  This may make sense for somebody who&amp;rsquo;s dedicated to a certain reader.  At the very least, the services supported by different apps are a big piece of the puzzle for those of us on the hunt for a new service.&lt;/p&gt;
&lt;h3 id=&#34;paid-sync-services&#34;&gt;Paid Sync Services&lt;/h3&gt;
&lt;p&gt;Finally, there is a market re-emerging for paid RSS sync services.  Services like this began to emerge before Google Reader emerged as a dominant free alternative.  Now that Reader is gone, the service has become economically viable again.  The market appears to be settling on a cost of $18 to $25 a year for RSS hosting.  Several services fall into that sweet spot, including &lt;a href=&#34;https://feedbin.me/&#34;&gt;Feedbin&lt;/a&gt; and &lt;a href=&#34;http://feedwrangler.net/welcome.html&#34;&gt;Feed Wrangler&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;what-now&#34;&gt;What now?&lt;/h2&gt;
&lt;p&gt;For now, the most important step for Google Reader refugees is to download your subscription information from Google.  Even if you&amp;rsquo;ve imported your information into a new service, it&amp;rsquo;s important to have a local copy, especially since several of the new services don&amp;rsquo;t support any export options.&lt;/p&gt;
&lt;p&gt;After that I&amp;rsquo;d recommend trying a couple of the new services.  They work differently, and reflect the different ways people use RSS.  For me personally, I found Feedly&amp;rsquo;s UI to be frustrating, and am still totally confused that Digg&amp;rsquo;s otherwise excellent offering seems to provide no way to view only view unread items.  I was also concerned by the lack of a business model for Feedly, and the fact that Digg Reader appears mostly dedicated to supporting Digg, rather than serving as a standalone business.  I didn&amp;rsquo;t seriously consider Fever or any other self-hosted services.  I want RSS to be a thought-free process for me, where I&amp;rsquo;m able to focus on the content and not the tool.  I&amp;rsquo;m willing to pay for that.&lt;/p&gt;
&lt;p&gt;In the end I&amp;rsquo;ve settled on Feedbin.  I&amp;rsquo;m paying the $2/month rate, and have been quite satisfied so far. It has a clean and usable web interface, and works with my favorite iPhone client &lt;a href=&#34;http://reederapp.com/&#34;&gt;Reeder&lt;/a&gt;. It also makes it easy to quickly scan unread items, and move all items to read, which fits my personal workflow.  Feedbin works for me.  I hope you find what works for you.&lt;/p&gt;
&lt;h2 id=&#34;related-reading&#34;&gt;Related Reading&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Marco Arment &lt;a href=&#34;http://www.marco.org/2013/06/28/all-or-nothing&#34;&gt;doesn&amp;rsquo;t see a future for proprietary sync services&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Dr Drang had a rough experience trying to &lt;a href=&#34;http://www.leancrew.com/all-this/2013/06/my-rss-failure/&#34;&gt;do it himself&lt;/a&gt;, but now &lt;a href=&#34;http://www.leancrew.com/all-this/2013/06/feedle-dee-dee/&#34;&gt;seems happy with Feed Wrangler&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;The Verge took a look at the more established options and &lt;a href=&#34;http://www.theverge.com/2013/3/19/4119006/the-best-google-reader-alternatives&#34;&gt;recommends Feedly&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>How I Use Stack Overflow</title>
      <link>https://benmccormick.org/2013/06/11/161900.html</link>
      <pubDate>Tue, 11 Jun 2013 17:19:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2013/06/11/161900.html</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;The problem with self directed learning is that our ability to learn is often constrained by the very problem we are trying to solve, our limited knowledge of a field.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;One of the first things I learned as I began to work in the software industry was that self driven learning is necessary for staying relevant.  Especially when working on evolving platforms like the web and mobile, things change fast.  The web frameworks of 2005 have little direct relevance to web development in 2013, and mobile development in its current form was a category that didn&amp;rsquo;t even exist in 2005.  If you want to be at the top of your field, or even anywhere close, learning and growing independently of whatever your current task happens to be is incredibly important.  But it can be hard to put into practice.&lt;/p&gt;
&lt;p&gt;The problem with self directed learning is that our ability to learn is often constrained by the very problem we are trying to solve, our limited knowledge of a field. Some of these problems resolve themselves quite easily.  A beginning Javascript programmer may not know that he needs to include a script in order to use the jQuery syntax he&amp;rsquo;s seen online, but he&amp;rsquo;ll discover it very quickly when his script fails to run.  But it&amp;rsquo;s quite possible to go on programming for years without realizing that it&amp;rsquo;s bad practice to couple your view and model too tightly, or even without gaining a deep understanding of how a web application model actually works. We create our models of how programming works, and it&amp;rsquo;s easy to stay inside those closed doors.  It can be easy to try and fit new languages into existing understandings, which is why you find people writing Java that looks like C and Javascript that looks like Java.  We don&amp;rsquo;t grow because we don&amp;rsquo;t ask the right questions.&lt;/p&gt;
&lt;h4 id=&#34;enter-stack-overflow&#34;&gt;Enter Stack Overflow&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;The killer feature when asking questions is that developers often won&amp;rsquo;t answer within the scope of what you asked; they&amp;rsquo;ll help you ask the right questions instead&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If the problem is that we don&amp;rsquo;t ask the right questions, a Q&amp;amp;A site may seem like a dubious solution.  But &lt;a href=&#34;http://stackoverflow.com/&#34;&gt;Stack Overflow&lt;/a&gt; has been the best tool I&amp;rsquo;ve ever found for self-directed learning. It&amp;rsquo;s a crazy hybrid between a wiki, Q&amp;amp;A site, forum, and video game originally conceived by &lt;a href=&#34;http://www.codinghorror.com/blog/&#34;&gt;Jeff Atwood&lt;/a&gt; and &lt;a href=&#34;http://www.joelonsoftware.com/&#34;&gt;Joel Spolsky&lt;/a&gt; back in 2008.  With ambitions to become a comprehensive programming archive for the web, the site has become a critical resource for programmers. In fact it&amp;rsquo;s the &lt;a href=&#34;http://www.alexa.com/siteinfo/stackoverflow.com&#34;&gt;92nd most visited website in the world&lt;/a&gt; as of June 2013.&lt;/p&gt;
&lt;p&gt;So how does StackOverflow enable self directed learning?  The most obvious way is allowing open-ended questions to be asked, with answers crowd-sourced from a global community of developers.  The killer feature when asking questions is that developers often won&amp;rsquo;t answer within the scope of what you asked; they&amp;rsquo;ll help you ask the right questions instead.  If you ask how to change the backgrounds of a group of DOM items given a list of ids, you&amp;rsquo;re likely to get an answer (or 5) while also helpfully being informed of the existence of classes.  Because multiple answers are allowed you may be exposed to multiple approaches. There is plenty to be learned this way.  Stack Overflow also helps automate this process by suggesting related questions as you type your questions, based on keywords.  The AI behind this is quite good, and usually causes me to abandon my question writing as I realize that my question has already been asked and answered.&lt;/p&gt;
&lt;h4 id=&#34;learning&#34;&gt;Learning&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;Questions asked by other people that you can&amp;rsquo;t answer are the best part of Stack Overflow&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Stack Overflow really began making a difference in my work and learning though when I moved past asking questions and also began contributing.  At the end of 2012 I started making a serious effort to begin answering questions, both as a way to contribute back to the community, and as a way of learning about my primary language at work, Javascript.  I was, and am, by no means a Javascript expert.  But I have learned a lot through the following process:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Browsing regularly through new questions under the Javascript and Coffeescript tags.&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Picking out interesting  questions that haven&amp;rsquo;t been answered satisfactorily yet.  If there are good answers that I can&amp;rsquo;t add to substantially, I upvote them.  If there are harmfully misleading or unhelpful answers I may downvote them with a comment.&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;If I know the answer to the question, I answer it, with an attempt to cite some sources for further information.  This happens sometimes, but much more often I don&amp;rsquo;t know the answer off the top of my head.  This is where learning takes place.&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;If I don&amp;rsquo;t know the answer I&amp;rsquo;ll try to research it.  This may involve some combination of:&lt;/em&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;em&gt;Making a test with jsFiddle and learning about the behavior hands on.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Looking up the relevant spec on MDN, Github, or library documentation&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Looking at related Stack Overflow questions to see if there are relevant resources or information there.&lt;/em&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;em&gt;Once I have an answer I&amp;rsquo;ll return to the original question.  Sometimes (usually in fact) somebody else will have beaten me to a response. If that happens, I evaluate whether I can add value.  If I can, I answer. If not I upvote the best answer and move on.&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This is where Stack Overflow really begins to show benefits.  When I do the research to answer a question I usually learn many things along with whatever the specific question was. Questions asked by other people that you can&amp;rsquo;t answer are the best part of Stack Overflow.  They are opportunities to not just expand your field of knowledge, but also to think about problems and solutions that you had never even contemplated.  So go, find a question that you don&amp;rsquo;t understand, and see what it takes to answer it.  You may just learn something.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Evergreen Browsers</title>
      <link>https://benmccormick.org/2013/06/11/134500.html</link>
      <pubDate>Tue, 11 Jun 2013 14:45:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2013/06/11/134500.html</guid>
      <description>&lt;p&gt;&lt;a href=&#34;http://tomdale.net/2013/05/evergreen-browsers/&#34;&gt;Tom Dale on Evergreen Browsers:&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If you’re like me, when you’re developing a new web application, you put features into mental buckets. There’s the “works in IE7″ bucket, the “works in IE8″ bucket, “(I think) works in IE9,” and of course, “works in MobileSafari.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;The one bucket I don’t have is the “works in Chrome” bucket. That’s too much mental overhead. Instead, if I want to test whether something works in Chrome, I just pop open a new JS Bin and try it out. I don’t worry about which version they’re on—I assume that by the time my code makes it to production, my users will be on more-or-less the same version as me.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;What would the web platform look like if every browser with significant market share updated itself at the same pace—and lack of user intervention—as Chrome?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I&amp;rsquo;m excited for this to happen.  Browser diversity is a good thing and worth the pain because it pushes things forward, but the advantages are lost when users aren&amp;rsquo;t moving forward along with the innovations that diversity and competition bring.  Having an up to date browser shouldn&amp;rsquo;t be a user concern.  Here&amp;rsquo;s to a web that moves at the pace of the leaders, rather than being paced by the least common denominator.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>90% Done, Halfway There</title>
      <link>https://benmccormick.org/2013/06/09/134500.html</link>
      <pubDate>Sun, 09 Jun 2013 14:45:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2013/06/09/134500.html</guid>
      <description>&lt;p&gt;There&amp;rsquo;s a running joke on my team at work when somebody asks about progress on another engineers bug.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;I&amp;rsquo;ve done 90% of the work, so I&amp;rsquo;m about halfway there!&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It&amp;rsquo;s really hard to estimate software development times.  I would in fact say that from a project planning perspective, that may be THE hardest problem when planning a big project.  Its certainly a question that engineers are asked all the time, and not one that is usually easy to answer even on an individual level.&lt;/p&gt;
&lt;h2 id=&#34;why-do-we-care&#34;&gt;Why do we care?&lt;/h2&gt;
&lt;p&gt;Estimating development time accurately is important both in the big picture and in day to day development work.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;It allows you to set healthy and reasonable expectations&lt;/li&gt;
&lt;li&gt;It allows for proper prioritization and planning of features&lt;/li&gt;
&lt;li&gt;It gives a team flexibility to make changes early if the current schedule is untenable&lt;/li&gt;
&lt;li&gt;It allows you on a personal level to properly prioritize and balance your time&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;why-is-this-so-hard&#34;&gt;Why Is This So Hard?&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ve been thinking about this lately, and I&amp;rsquo;ve identified the factors that I&amp;rsquo;ve found contribute the most to the &amp;ldquo;90% done, halfway there&amp;rdquo; mindset.&lt;/p&gt;
&lt;h3 id=&#34;scale&#34;&gt;Scale&lt;/h3&gt;
&lt;p&gt;The first factor is also the most inevitable.  More code, bigger teams, and more complex requirements all make software estimation harder.  When I work alone on a side project, I rarely have trouble estimating how long a particular feature will take to implement.  This is true for a few reasons.  First, and most importantly, I know and understand all of the code in the project.  If I see code that looks out of place, I either remember, or can quickly work out, why it was put there.  I also have a comfort level with all the tools and technologies in use because I chose them myself, and have either used them before or specifically wanted to learn them.&lt;/p&gt;
&lt;p&gt;Working in a larger team however means greater uncertainty about the original intentions of existing code, less familiarity with the code base as a whole, and (on sufficiently large projects) possibly an acceptance that you cannot understand the whole code base.  This unfamiliarity is usually mitigated by having engineers focus within a specific portion of the code.  That is a great strategy, provided our second problem is not present.&lt;/p&gt;
&lt;h3 id=&#34;tight-coupling&#34;&gt;Tight Coupling&lt;/h3&gt;
&lt;p&gt;When it comes to issues within the code base itself, I think the biggest obstacle to accurately estimating development time is tightly coupled software components.  Anybody who&amp;rsquo;s ever read &lt;a href=&#34;http://www.amazon.com/The-Pragmatic-Programmer-Journeyman-Master/dp/020161622X&#34;&gt;The Pragmatic Programmer&lt;/a&gt; can tell you that tight coupling is a &lt;em&gt;BAD THING&lt;/em&gt;, but in practice it can be seductively easy to fall into.  The problem is that tight coupling means that when making changes to a piece of code you don&amp;rsquo;t have to worry just about its internal function, but also about side effects.  When combined with the first issue of scale, this means that changes to code you&amp;rsquo;re working on may have effects on other code that you don&amp;rsquo;t fully understand or anticipate.  Too much of this can easily lead to&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;90% done, and now I have 4 more bugs to work on.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;defining-coding-as-the-task&#34;&gt;Defining Coding As The Task&lt;/h3&gt;
&lt;p&gt;The first 2 issues are to a certain extent unavoidable when working on a large existing code base like my teams.  But bad estimates can also  appear for reasons completely unrelated to the particular problem or code base. One issue that can be a problem for a programmer on a new team and also cause issues with programmer-manager communication is viewing coding as the task, without worrying about design, testing, documentation or code reviews.  When the programmer says to his manager that something is a 3 line fix what he&amp;rsquo;s really saying is that the coding seems easy so the rest should be quick.  If his initial solution has problems, he not only is missing the time to write a new one, but also the time for it to be discovered by test, formulating a new design, and any review or paperwork required for making the change.&lt;/p&gt;
&lt;h3 id=&#34;poor-communication&#34;&gt;Poor Communication&lt;/h3&gt;
&lt;p&gt;Finally the easiest way to be 90% done and only halfway there is to spend your first 90% writing the wrong code.  When the specs aren&amp;rsquo;t clear and the programmer doesn&amp;rsquo;t understand the requirement (whether it comes from a customer, test, or a project manager)  wasted time and poor estimates are pretty much a given.  The key here is the same as the last point.  There is more to software development than just writing code.&lt;/p&gt;
&lt;h2 id=&#34;improvement&#34;&gt;Improvement&lt;/h2&gt;
&lt;p&gt;So how can we do better?  I&amp;rsquo;m still learning.  But here is the main way that I&amp;rsquo;m trying to do to get better at this.&lt;/p&gt;
&lt;h3 id=&#34;tightening-the-feedback-loop&#34;&gt;Tightening The Feedback Loop&lt;/h3&gt;
&lt;p&gt;One thing that can really improve the communication issues, and also make you aware of any tight coupling early on is tightening the feedback loop for your code.  What is that?  It means working to find out about errors and problems as soon as possible. Some ways to do this:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Automated Testing&lt;/li&gt;
&lt;li&gt;Asserts or other constructs to test assumptions&lt;/li&gt;
&lt;li&gt;Early prototypes of even small features to show requirement-setters&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I&amp;rsquo;ve known for a while that there&amp;rsquo;s value in building a subset of a feature to make sure I&amp;rsquo;m on the right track before coding the rest.  If a picture is worth 1000 words, working code is worth 1000 emails.  When you build something, even if its only partial or simplistic, you immediately get a sense for the challenges involved, and you also get the chance to immediately find out whether you are on the same page as the requirement creators.  For many people, especially non-programmers, its much easier to critique an existing system than to describe one ex nihilo.&lt;/p&gt;
&lt;p&gt;Several of us are also working to introduce more automated testing on our team.  We have a great team of manual testers, but there is great value in the immediate feedback that automated testing can bring, especially in revealing the type of unexpected side effects that tight coupling causes.&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary&lt;/h2&gt;
&lt;p&gt;Software Development estimation is hard. There are a variety of challenges, some of them inherent to the practice or certain projects, some of which can be overcome or mitigated through experience and attention.  In the end, accurate estimation is a skill worth cultivating, bringing value to both you and the team. Take the time, get it right.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Got some great tips for estimating software development times? Let me hear them on twitter &lt;a href=&#34;https://www.twitter.com/_benmccormick&#34;&gt;@_benmccormick&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Customer Culture Revisited</title>
      <link>https://benmccormick.org/2013/06/08/134500.html</link>
      <pubDate>Sat, 08 Jun 2013 14:45:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2013/06/08/134500.html</guid>
      <description>&lt;p&gt;&lt;a href=&#34;http://www.marco.org/2011/09/17/customer-culture-apple-and-microsoft&#34;&gt;Marco Arment back in 2011&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;For Windows 8 to succeed, especially for its tablets to compete well against the iPad, it will need to adopt a more Apple-like confidence to say “no” to its customers when they ask for everything under the sun. And, surprisingly, they might be doing exactly that.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;One of the reasons Metro is interesting to people like me who usually ignore Microsoft is that it’s full of very un-Microsoft-like decisions, generally for the better.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;The question isn’t whether Metro will be good: it probably will be. And that’s a huge accomplishment for Microsoft that they should be commended for.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;But how will their customers react?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Will Metro be meaningfully adopted by PC users? Or will it be a layer that most users disable immediately or use briefly and then forget about, like Mac OS X’s Dashboard, in which case they’ll deride the Metro-only tablets as “useless” and keep using Windows like they always have?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Almost 2 years later, this is looking extremely prescient.  I like what Microsoft was attempting to create with Windows 8, and love the Metro/Modern/Whatever style in general, but 8.1 seems to signal most of the effort since has been spent &lt;a href=&#34;http://arstechnica.com/information-technology/2013/06/windows-8-1-gains-boot-to-desktop-to-attract-business-users/&#34;&gt;hedging on it&lt;/a&gt; instead of doubling down, and I can&amp;rsquo;t see how its going to get where it needs to go like that.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Revertible Observables in Knockout</title>
      <link>https://benmccormick.org/2013/05/07/150500.html</link>
      <pubDate>Tue, 07 May 2013 16:05:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2013/05/07/150500.html</guid>
      <description>&lt;p&gt;Last week I was looking for a way to use KnockoutJS on a configuration menu that required the user to be able to cancel or accept their input after filling out the menu.&lt;/p&gt;
&lt;p&gt;Initially I was just copying the initial data and refilling my data model manually on cancel.  I wasn&amp;rsquo;t satisfied with that solution though.  It didn&amp;rsquo;t seem like it would scale well if the menu got more complicated, and it lacked the elegance and frictionless nature of most knockout data management.&lt;/p&gt;
&lt;p&gt;After some searching I found &lt;a href=&#34;http://www.knockmeout.net/2011/03/guard-your-model-accept-or-cancel-edits.html&#34;&gt;Ryan Niemeyer&amp;rsquo;s Protected Observable example&lt;/a&gt;, and it initially seemed like exactly what I wanted, a way to only persist changes to the view model if they were explicitly confirmed.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;//knockout-protected.js
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;//https://gist.github.com/benmccormick/5537138
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;
&lt;span style=&#34;color:#6272a4&#34;&gt;//wrapper to an observable that requires accept/cancel
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;ko.protectedObservable &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(initialValue) {
    &lt;span style=&#34;color:#6272a4&#34;&gt;//private variables
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; _actualValue &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; ko.observable(initialValue),
        _tempValue &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; initialValue;

    &lt;span style=&#34;color:#6272a4&#34;&gt;//computed observable that we will return
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; result &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; ko.computed({
        &lt;span style=&#34;color:#6272a4&#34;&gt;//always return the actual value
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;        read&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;() {
           &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; _actualValue();
        },
        &lt;span style=&#34;color:#6272a4&#34;&gt;//stored in a temporary spot until commit
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;        write&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(newValue) {
             _tempValue &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; newValue;
        }
    });

    &lt;span style=&#34;color:#6272a4&#34;&gt;//if different, commit temp value
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    result.commit &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;() {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (_tempValue &lt;span style=&#34;color:#ff79c6&#34;&gt;!==&lt;/span&gt; _actualValue()) {
             _actualValue(_tempValue);
        }
    };

    &lt;span style=&#34;color:#6272a4&#34;&gt;//force subscribers to take original
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    result.reset &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;() {
        _actualValue.valueHasMutated();
        _tempValue &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; _actualValue();   &lt;span style=&#34;color:#6272a4&#34;&gt;//reset temp value
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    };

    &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; result;
};

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;There was a problem with this approach though.  Ryan&amp;rsquo;s model saves the update to a temporary value and then moves it into an observable if the result is committed.  That works great for simple models and mostly behaves well if the user cancels out of the edit screen without committing or resetting. But it breaks down if you have another computed observable that depends on the value of the protected observable.  In my case I had an output that I wanted to show dynamically changing based on the input allowing experimentation.  Here&amp;rsquo;s a simplified example using a protected observable:&lt;/p&gt;
&lt;iframe width=&#34;100%&#34; height=&#34;300&#34; src=&#34;https://jsfiddle.net/tc299/4/embedded/&#34; allowfullscreen=&#34;allowfullscreen&#34; frameborder=&#34;0&#34;&gt;&lt;/iframe&gt;
&lt;p&gt;As you can see, the tables field doesn&amp;rsquo;t update until you confirm the entry. Ideally though we&amp;rsquo;d like it to update as the user changes their guest number, so they can see the effect on cost and space used before they confirm a change in guests.  We want to do this while still preserving the users abilities to cancel changes if they don&amp;rsquo;t like the results though.  So how to we do this?  We make a small change to the default value returned by the protected observable.  Here&amp;rsquo;s what I&amp;rsquo;m calling a Revertible Observable:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;/*
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;knockout-revertible.js
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;https://gist.github.com/benmccormick/5537115
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;*/&lt;/span&gt;

 &lt;span style=&#34;color:#6272a4&#34;&gt;//wrapper to an observable that requires accept/cancel
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;ko.revertibleObservable &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(initialValue) {
    &lt;span style=&#34;color:#6272a4&#34;&gt;//private variables
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; _actualValue &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; initialValue,
        _tempValue &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; ko.observable(initialValue);

    &lt;span style=&#34;color:#6272a4&#34;&gt;//computed observable that we will return
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; result &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; ko.computed({
        &lt;span style=&#34;color:#6272a4&#34;&gt;//always return the current value
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;        read&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;() {
           &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; _tempValue();
        },
        &lt;span style=&#34;color:#6272a4&#34;&gt;//stored in a temporary spot until commit
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;        write&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(newValue) {
             _tempValue(newValue);
        }
    });

    &lt;span style=&#34;color:#6272a4&#34;&gt;//if different, commit temp value
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    result.commit &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;() {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (_tempValue() &lt;span style=&#34;color:#ff79c6&#34;&gt;!==&lt;/span&gt; _actualValue) {
            _tempValue.valueHasMutated();
             _actualValue &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; _tempValue();
        }
    };

    &lt;span style=&#34;color:#6272a4&#34;&gt;//force subscribers to take original
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    result.reset &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;() {
        _tempValue(_actualValue);   &lt;span style=&#34;color:#6272a4&#34;&gt;//reset temp value
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    };

    &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; result;
};

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This preserves the ability to see the results of your changes in realtime, while also allowing you to easily revert with a simple cancel button and no explicit data tracking.  Now our example can work as we&amp;rsquo;d like, with the customer getting immediate feedback on how their guest changes effect the total cost.&lt;/p&gt;
&lt;iframe width=&#34;100%&#34; height=&#34;300&#34; src=&#34;https://jsfiddle.net/QQYrL/8/embedded/&#34; allowfullscreen=&#34;allowfullscreen&#34; frameborder=&#34;0&#34;&gt;&lt;/iframe&gt;
&lt;p&gt;Note that this isn&amp;rsquo;t a silver bullet.  An explicit confirmation is no longer required for the changes to be passed through, so its important to make sure that the user either confirms or resets the values after entering them.  But it allows for instant feedback on changes while still supporting the ability to dump the changes if the user decides they don&amp;rsquo;t like the result.  I think its a useful pattern for any situation where the user is entering data and you want to show them a preview of the outcome.  I hope others will find it as useful as I have.&lt;/p&gt;
&lt;h3 id=&#34;update&#34;&gt;Update&lt;/h3&gt;
&lt;p&gt;I showed this to Ryan and he replied with a nice simplification of the concept.&lt;/p&gt;
&lt;blockquote class=&#34;twitter-tweet&#34;&gt;&lt;p&gt;@&lt;a href=&#34;https://twitter.com/_benmccormick&#34;&gt;ben336&lt;/a&gt; nice Ben. I have had to do something similar in the past. Here is a simplified version that I have used: &lt;a href=&#34;http://t.co/IiqFe90kwi&#34; title=&#34;https://jsfiddle.net/rniemeyer/SFCgr/&#34;&gt;jsfiddle.net/rniemeyer/SFCg…&lt;/a&gt;&lt;/p&gt;&amp;mdash; Ryan Niemeyer (@RPNiemeyer) &lt;a href=&#34;https://twitter.com/RPNiemeyer/status/331954950009663488&#34;&gt;May 8, 2013&lt;/a&gt;&lt;/blockquote&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;//Ryan Niemeyer&amp;#39;s simplified knockout-revertible.js
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;//https://jsfiddle.net/rniemeyer/SFCgr/ Fiddle
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt; ko.revertibleObservable &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(initialValue) {
    &lt;span style=&#34;color:#6272a4&#34;&gt;//private variables
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; result &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; ko.observable(initialValue);

    result.forEditing &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; ko.observable(initialValue);

    &lt;span style=&#34;color:#6272a4&#34;&gt;//if different, commit edit value
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    result.commit &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;() {
        &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; editValue &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; result.forEditing();

        &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; (editValue &lt;span style=&#34;color:#ff79c6&#34;&gt;!==&lt;/span&gt; result()) {
            result(editValue);
        }
    };

    &lt;span style=&#34;color:#6272a4&#34;&gt;//force subscribers to take original
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    result.reset &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;() {
        result.forEditing(result());
    };

    &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; result;
};

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Irreplaceable</title>
      <link>https://benmccormick.org/2013/05/04/120000.html</link>
      <pubDate>Sat, 04 May 2013 13:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2013/05/04/120000.html</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;If you are the average worker in the average job then you can be replaced. The reason I tell people this is because I want to help them realize that there are important things in life and then there are VERY important things in life. Make sure you are good in the areas of life that you aren’t replaceable (family) and then focus on the other areas (work). This is my view, but I think anyone with a family probably feels the same way. Telling someone they are replaceable is a great cure for arrogance.&lt;/p&gt;
&lt;p&gt;I appreciate the work that my folks do and tell them that, but Microsoft will go on without them. Think about the last time someone left your team. How long did it take before they were a distant memory? Probably a day or so then the team moves on with their work. I&amp;rsquo;m not saying don&amp;rsquo;t care about work. I&amp;rsquo;m saying care about the VERY important things more. If your work/life balance is off and the VERY important things are threatened, then take a break and get some help.&lt;/p&gt;
&lt;p&gt;At work you can be replaced in about 5 minutes, but you are effectively irreplaceable at home. Keep that in mind. I think about it every day.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&#34;http://blog.jongallant.com/2013/05/work-life-balance-at-microsoft.html?goback=.gde_42347_member_237479036&amp;amp;m=1&#34;&gt;My Thoughts on Work/Life Balance at Microsoft- Jon Gallant&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Jon Gallant speaks the truth.  Aside from any personal beliefs on which is more important or meaningful&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; rel=&#34;footnote&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;, its pretty clear that it would be much easier for your employer to find somebody to do your job than it would be for your spouse/children to find their way without you.  We all have a desire to be significant and necessary I think, we just don&amp;rsquo;t always value it in the places we are.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34;&gt;&lt;ol&gt;
    &lt;li class=&#34;footnote&#34; id=&#34;fn:1&#34;&gt;
        &lt;p&gt;I fully agree with him on that. Family will always be first for me. &lt;a href=&#34;#fnref:1&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
&lt;/ol&gt;&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Book Review: Javascript Testing with Jasmine</title>
      <link>https://benmccormick.org/2013/04/23/153000.html</link>
      <pubDate>Tue, 23 Apr 2013 16:30:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2013/04/23/153000.html</guid>
      <description>&lt;p&gt;I received a copy of Javascript Testing with Jasmine by Evan Hahn this week, and it seemed like perfect timing.  The developers on my team at work have been discussing using Jasmine to automate the testing of Javascript code in our product, and I may be spending a significant amount of time with it soon.  I was hoping to pick up on some tips and tricks, and maybe learn some things about testing.  It ended up being a quick read with some useful tidbits that left me wanting more.&lt;/p&gt;
&lt;h3 id=&#34;what-is-it&#34;&gt;What is it?&lt;/h3&gt;
&lt;p&gt;Javascript Testing with Jasmine is a short little book about testing with Jasmine, a testing framework inspired by the Behavior Driven Development style.  The book is short (only 52 pages), which is appropriate for its limited scope. It&amp;rsquo;s split into 7 chapters with each chapter comprised of a few pages of example and explanation:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;What is Software testing?&lt;/li&gt;
&lt;li&gt;Jasmine&lt;/li&gt;
&lt;li&gt;Writing good tests&lt;/li&gt;
&lt;li&gt;Matchers in depth&lt;/li&gt;
&lt;li&gt;More Jasmine Features&lt;/li&gt;
&lt;li&gt;Spies&lt;/li&gt;
&lt;li&gt;Using Jasmine with other tools&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;whats-it-like&#34;&gt;What&amp;rsquo;s it like?&lt;/h3&gt;
&lt;p&gt;Unfortunately the book manages to simultaneously feel like its filling space in many spots, and like it missed opportunities to provide value in others. Chapters 4 and 5 for instance fail to say much that is not already in Jasmine&amp;rsquo;s &lt;a href=&#34;http://pivotal.github.io/jasmine//&#34;&gt;&amp;ldquo;describe by showing&amp;rdquo;-style documentation.&lt;/a&gt; Chapter 1 seems to be searching for interesting things to say about testing, and failed to meaningfully explain the distinction between BDD and generic Test Driven Development.  The section on Jasmine and Coffeescript in Chapter 7 could be succinctly summarized as &amp;ldquo;Yes you can use Jasmine with Coffeescript&amp;rdquo;.  At the same time, the book misses opportunities to talk about things like writing testable code, or refactoring existing code to be meaningfully tested with Jasmine. I would have loved to see more about automating testing and fitting it into the development process, or running tests from the command line with phantomJS.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s not to say that there&amp;rsquo;s nothing good here.  I found the explanation of spies to be very helpful, and the detailed documentation-like aspects would be more helpful to a Javascript beginner than Jasmine&amp;rsquo;s &lt;strong&gt;&amp;ldquo;show me the code&amp;rdquo;&lt;/strong&gt; docs.  All in all the book serves as a great reference guide for the library.  I&amp;rsquo;m just not sure how much value it adds compared to a quick Google search.&lt;/p&gt;
&lt;h3 id=&#34;summary&#34;&gt;Summary&lt;/h3&gt;
&lt;p&gt;In the end this feels like the type of book that made sense before Google took over the Internet.  It provides all the basic how-tos and background information, but fails to provide any deep insight.  If you&amp;rsquo;re starting a new Javascript BDD project and want a quick reference this may make sense as a quick reference guide, but for most people the information in here can be found just as easily with a little use of your favorite search engine and a trip to the Jasmine docs.&lt;/p&gt;
&lt;h3 id=&#34;where-can-i-buy-it&#34;&gt;Where can I buy it?&lt;/h3&gt;
&lt;p&gt;You can get it from Amazon here: &lt;a href=&#34;http://www.amazon.com/gp/product/1449356370/ref=as_li_tl?ie=UTF8&amp;camp=1789&amp;creative=390957&amp;creativeASIN=1449356370&amp;linkCode=as2&amp;tag=benmccormicko-20&amp;linkId=JTR6CUZAHM7HLHOQ&#34;&gt;JavaScript Testing with Jasmine (Affiliate Link)&lt;/a&gt;&lt;img src=&#34;http://ir-na.amazon-adsystem.com/e/ir?t=benmccormicko-20&amp;l=as2&amp;o=1&amp;a=1449356370&#34; width=&#34;1&#34; height=&#34;1&#34; border=&#34;0&#34; alt=&#34;&#34; style=&#34;border:none !important; margin:0px !important;&#34; /&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&#34;further-reading&#34;&gt;Further Reading&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://pivotal.github.io/jasmine//&#34;&gt;Jasmine Home Page&lt;/a&gt; - Learn more about Jasmine straight from the source&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://blog.mediumequalsmessage.com/book-review-javascript-testing-with-jasmine&#34;&gt;Medium Equals Message&lt;/a&gt; - another review of the book from Chris Webb&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This review is part of the &lt;a href=&#34;http://oreilly.com/bloggers/&#34;&gt;O&amp;rsquo;Reilly Blogger Program&lt;/a&gt;.  I am not compensated for this review, but did receive a free review copy of the book.  The opinions expressed here are my own.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>A New Look</title>
      <link>https://benmccormick.org/2013/04/06/120000.html</link>
      <pubDate>Sat, 06 Apr 2013 13:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2013/04/06/120000.html</guid>
      <description>&lt;p&gt;I&amp;rsquo;m switching to a modified version of the excellent &lt;a href=&#34;https://github.com/gluttony/object-octopress-theme&#34;&gt;Object&lt;/a&gt; theme by &lt;a href=&#34;https://github.com/gluttony&#34;&gt;gluttony&lt;/a&gt; for this blog.  I like the cleaner content-focused look that it brings, and especially feel like it helps my code samples stand out.  I hope you like it.&lt;/p&gt;
&lt;p&gt;My site continues to be generated as static pages by &lt;a href=&#34;http://octopress.org/&#34;&gt;octopress&lt;/a&gt;, and written using &lt;a href=&#34;http://www.sublimetext.com/&#34;&gt;Sublime Text&lt;/a&gt;.  Both are unreservedly recommended.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Creating a Build System For a Coffeescript Project with Ant</title>
      <link>https://benmccormick.org/2013/03/23/112300.html</link>
      <pubDate>Sat, 23 Mar 2013 12:23:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2013/03/23/112300.html</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve recently taken the time to develop an organized build system for a &lt;a href=&#34;http://Coffeescript.org/&#34;&gt;Coffeescript&lt;/a&gt; and &lt;a href=&#34;http://sass-lang.com/&#34;&gt;SASS&lt;/a&gt; &lt;a href=&#34;https://bitbucket.org/ben336/scratchcalc&#34;&gt;project&lt;/a&gt; that I&amp;rsquo;ve been working on in my free time.  I learned a lot during the process, and I wanted to share my experience here.  I used Ant for my build system, and worked in a variety of different libraries for minification, testing and documentation.&lt;/p&gt;
&lt;h3 id=&#34;getting-started&#34;&gt;Getting Started&lt;/h3&gt;
&lt;p&gt;The first step is to install Ant.  It comes preinstalled on OSX, is &lt;a href=&#34;http://www.rndblog.com/how-to-install-ant-on-linux/&#34;&gt;fairly straightforward&lt;/a&gt; to install on Linux, and is &lt;a href=&#34;http://www.nczonline.net/blog/2012/04/12/how-to-install-apache-ant-on-windows/&#34;&gt;a bit more involved&lt;/a&gt; to install on Windows  If you&amp;rsquo;re using my exact setup, you&amp;rsquo;ll also need &lt;a href=&#34;http://nodejs.org/&#34;&gt;NodeJS&lt;/a&gt; (for Coffeescript, UglifyJS,and Docco) and &lt;a href=&#34;http://www.ruby-lang.org/&#34;&gt;Ruby&lt;/a&gt; (for SASS) installed.&lt;/p&gt;
&lt;h3 id=&#34;my-project-structure&#34;&gt;My Project Structure&lt;/h3&gt;
&lt;p&gt;I went for a structure with 4 directories.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;src&lt;/li&gt;
&lt;li&gt;build&lt;/li&gt;
&lt;li&gt;test&lt;/li&gt;
&lt;li&gt;docs&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All of the source files are in the source directory, with Javascript and Coffeescript files in a scripts directory, and SASS styles in a styles folder.  This particular app has only a single HTML file, which sits in the root of the source directory.  The test folder contains a single HTML page, and a series of unit test files written in Coffeescript, in a structure that mirrors the src directory.  The build and docs directories are initially empty.&lt;/p&gt;
&lt;h3 id=&#34;the-basics&#34;&gt;The Basics&lt;/h3&gt;
&lt;p&gt;We start with a simple Ant setup.  We&amp;rsquo;ll create an init task, a clean task, and debug and production tasks.  The following code goes into our build.xml file, which is placed at the root of the project directory.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;project name=&amp;quot;scratchcalc&amp;quot; default=&amp;quot;debug&amp;quot;&amp;gt;

    &amp;lt;loadproperties srcfile=&amp;quot;build.properties&amp;quot; /&amp;gt;

    &amp;lt;target name=&amp;quot;debug&amp;quot; depends=&amp;quot;clean, init&amp;quot;&amp;gt;
        &amp;lt;echo&amp;gt;ScratchCalc Version ${version} (Debug Version)&amp;lt;/echo&amp;gt;
    &amp;lt;/target&amp;gt;

    &amp;lt;target name=&amp;quot;production&amp;quot; depends=&amp;quot;clean, init&amp;quot;&amp;gt;
        &amp;lt;echo&amp;gt;ScratchCalc Version ${version}&amp;lt;/echo&amp;gt;
    &amp;lt;/target&amp;gt;

    &amp;lt;target name= &amp;quot;init&amp;quot;&amp;gt;
        &amp;lt;mkdir dir=&amp;quot;${build.dir}&amp;quot; /&amp;gt;
    &amp;lt;/target&amp;gt;

    &amp;lt;target name=&amp;quot;clean&amp;quot;&amp;gt;
        &amp;lt;delete dir=&amp;quot;${build.dir}&amp;quot; /&amp;gt;
    &amp;lt;/target&amp;gt;

&amp;lt;/project&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So for this project, we now have 4 tasks that we can call.  To call the init task, all we need to do is run&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Ant init
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;from the command line.   Both our debug and production tasks mark clean and init as dependencies, so running them will remove and restore the build directory.  Beyond that, our build doesn&amp;rsquo;t do much right now.  Lets change that.&lt;/p&gt;
&lt;h3 id=&#34;copying&#34;&gt;Copying&lt;/h3&gt;
&lt;p&gt;The simplest thing we can do with our Ant file is basic copying of files.  So lets start with a task that just copies over our files from the src directory to the build directory.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-xml&#34; data-lang=&#34;xml&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;target&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;name=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;copy&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;description=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;Copies files from src to build dirs&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;
    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;echo&amp;gt;&lt;/span&gt;Copying JS, CSS &amp;amp; HTML Files&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;/echo&amp;gt;&lt;/span&gt;
     &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;copy&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;todir=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;${build.dir}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;
        &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;fileset&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;dir=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;${src.dir}&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;includes=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;**/*.HTML,**/*.css,**/*.js&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;/&amp;gt;&lt;/span&gt;
     &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;/copy&amp;gt;&lt;/span&gt;
&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;/target&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This simply copies any HTML, CSS, or Javascript files in the src directory over to an equivalent position in the build directory.  The segments in the &lt;code&gt;${}&lt;/code&gt; format are variables defined in our build.properties file.  For my project, that looks something like this so far:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;version = 0.0.1
copyright = Copyright 2012-2013 Ben McCormick.
src.dir = ./src
build.dir = ./build
test.dir = ./test
lib.dir = ${src.dir}/ext
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This would be a great place to start for a project thats currently running without a build system.  If you&amp;rsquo;re able to get your project to build like this, it will set you up to be able to start more interesting things going forward.&lt;/p&gt;
&lt;p&gt;And we of course want to do more interesting things.  This project uses Coffeescript and SASS, so we&amp;rsquo;ll need to do a bit more than just copy files.  So lets copy those scripts as well, but convert them to Javascript and CSS while we do.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-xml&#34; data-lang=&#34;xml&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;target&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;name=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;copy&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;description=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;Compiles Coffeescript and SASS files,copies the rest&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;
    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;echo&amp;gt;&lt;/span&gt;Copying Coffeescript Files&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;/echo&amp;gt;&lt;/span&gt;
     &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;copy&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;todir=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;${build.dir}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;
        &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;fileset&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;dir=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;${src.dir}&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;includes=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;**/*.HTML,**/*.css,**/*.js&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;/&amp;gt;&lt;/span&gt;
     &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;/copy&amp;gt;&lt;/span&gt;
     &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;exec&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;executable=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;coffee&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;
          &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;arg&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;value=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;--compile&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;/&amp;gt;&lt;/span&gt;
          &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;arg&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;value=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;--map&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;/&amp;gt;&lt;/span&gt;
          &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;arg&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;value=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;--output&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;/&amp;gt;&lt;/span&gt;
          &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;arg&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;value=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;${build.script.dir}&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;/&amp;gt;&lt;/span&gt;
          &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;arg&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;value=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;${src.script.dir}&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;/&amp;gt;&lt;/span&gt;
     &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;/exec&amp;gt;&lt;/span&gt;
     &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;mkdir&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;dir=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;${build.styles.dir}&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;/&amp;gt;&lt;/span&gt;
     &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;apply&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;executable=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;sass&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;dest=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;${build.dir}&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;verbose=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;true&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;force=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;true&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;failonerror=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;true&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;
        &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;arg&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;value=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;--unix-newlines&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;/&amp;gt;&lt;/span&gt;
        &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;srcfile&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;/&amp;gt;&lt;/span&gt;
        &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;targetfile&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;/&amp;gt;&lt;/span&gt;
        &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;filelist&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;dir =&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;${src.dir}&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;files=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;styles/scratch.sass&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;/&amp;gt;&lt;/span&gt;
        &lt;span style=&#34;color:#6272a4&#34;&gt;&amp;lt;!--&amp;lt;fileset dir=&amp;#34;${src.dir}&amp;#34; includes=&amp;#34;**/*.sass&amp;#34;  /&amp;gt;--&amp;gt;&lt;/span&gt;
        &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;mapper&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;type=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;glob&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;from=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;*.sass&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;to=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;*.css&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;/&amp;gt;&lt;/span&gt;
    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;/apply&amp;gt;&lt;/span&gt;
&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;/target&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So along with copying the raw files, we also now copy the Coffeescript and SASS files.  For Coffeescript, we run the coffee executable against the entire src dir, and have it mirror the output to the build dir.  For Sass, we only want to run the compile on a single file, which pulls all of the other files into it through import statements.  So we use the filelist and mapper to specify the input and output files.&lt;/p&gt;
&lt;h3 id=&#34;concatenation&#34;&gt;Concatenation&lt;/h3&gt;
&lt;p&gt;Mirroring your directory can be helpful for debugging, and is a good initial step if you&amp;rsquo;re converting to Ant from a locally run project.  But we&amp;rsquo;d really like to limit the amount of requests we make when deploying our site.  To do that, we&amp;rsquo;ll concatenate the js files together.  For my project I create 2 files, one for my external dependencies, and one for my own local files.  I may eventually reduce this to 1, but for now I like separating the 2 for debugging clarity.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-xml&#34; data-lang=&#34;xml&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;target&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;name=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;concatenatejs&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;description=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;Concatenate All the JS together&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;
    &lt;span style=&#34;color:#6272a4&#34;&gt;&amp;lt;!-- Instead of concatenating the JS files directly, use coffee to preserve the source map --&amp;gt;&lt;/span&gt;
    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;echo&amp;gt;&lt;/span&gt;Concatenating the JS&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;/echo&amp;gt;&lt;/span&gt;
    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;concat&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;destfile=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;${build.libs}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;
         &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;filelist&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;dir =&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;${build.script.dir}&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;files=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;lib/jquery.js,lib/knockout.js,lib/BigDecimal.js&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;/&amp;gt;&lt;/span&gt;

          &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;fileset&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;dir=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;${build.script.dir}/lib&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;includes=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;**/*.js&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;/&amp;gt;&lt;/span&gt;
    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;/concat&amp;gt;&lt;/span&gt;
    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;apply&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;executable=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;coffee&amp;#34;&lt;/span&gt;  &lt;span style=&#34;color:#50fa7b&#34;&gt;verbose=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;true&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;force=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;true&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;failonerror=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;true&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;parallel=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;true&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;
    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;arg&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;value=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;--compile&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;/&amp;gt;&lt;/span&gt;
    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;arg&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;value=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;--map&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;/&amp;gt;&lt;/span&gt;
    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;arg&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;value=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;--join&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;/&amp;gt;&lt;/span&gt;
    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;arg&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;value=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;${build.script.output}&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;/&amp;gt;&lt;/span&gt;
    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;srcfile&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;/&amp;gt;&lt;/span&gt;
    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;filelist&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;dir =&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;${src.script.dir}&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;files=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;editor/toolkit.coffee,editor/markupGen.coffee,parser/eqTreeBuilder.coffee,parser/NumberValue.coffee,parser/eqScanner.coffee,parser/eqTokenizer.coffee,parser/tablePlaceHolder.coffee,parser/EQParser.coffee,parser/calcFramework.coffee,editor/editor.coffee&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;/&amp;gt;&lt;/span&gt;
    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;/apply&amp;gt;&lt;/span&gt;
&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;/target&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For the external libraries I use Ant&amp;rsquo;s built in &lt;code&gt;concat&lt;/code&gt; task to concatenate the files together.  For the Coffeescript files, I use the coffee compiler rather than concatenating the files that I copied.  I was hoping to do this in order to preserve the source map, which allows for easier debugging.  Unfortunately the compiler has trouble generating source maps for joined files right now.  I&amp;rsquo;m hoping to fix that in the future, in the meantime I may be using a different approach, possibly using uglifyjs to concatenate the files and generate the maps.&lt;/p&gt;
&lt;h2 id=&#34;minify&#34;&gt;Minify&lt;/h2&gt;
&lt;p&gt;Speaking of &lt;a href=&#34;https://github.com/mishoo/UglifyJS2&#34;&gt;uglifyjs&lt;/a&gt;, I use that for minifying my Javascript.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-xml&#34; data-lang=&#34;xml&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;target&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;name=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;minify&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;description=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;Minify the JS for Production&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;
    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;echo&amp;gt;&lt;/span&gt;Minifying the JS For Production with UglifyJS&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;/echo&amp;gt;&lt;/span&gt;
    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;apply&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;executable=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;uglifyjs&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;verbose=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;true&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;force=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;true&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;failonerror=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;true&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;
        &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;srcfile&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;/&amp;gt;&lt;/span&gt;
        &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;arg&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;value=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;--output&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;/&amp;gt;&lt;/span&gt;
        &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;arg&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;value=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;${build.script.output}&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;/&amp;gt;&lt;/span&gt;
        &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;filelist&lt;/span&gt;  &lt;span style=&#34;color:#50fa7b&#34;&gt;files =&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;${build.script.output}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;/&amp;gt;&lt;/span&gt;
    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;/apply&amp;gt;&lt;/span&gt;
&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;/target&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I only require this for the production task, and leave the full source available for the debug task to preserve the readability of the generated JS.&lt;/p&gt;
&lt;h3 id=&#34;documentation&#34;&gt;Documentation&lt;/h3&gt;
&lt;p&gt;I use &lt;a href=&#34;http://jashkenas.github.com/docco&#34;&gt;docco&lt;/a&gt; for my Coffeescript documentation.  It converts comments into documentation and runs them through a &lt;a href=&#34;http://daringfireball.net/projects/markdown/&#34;&gt;Markdown&lt;/a&gt; parser to generate a clean HTML page with the code and comments intermingled.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-xml&#34; data-lang=&#34;xml&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;target&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;name=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;documentation&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;description=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;Generate Docco Documentation for coffee files&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;
    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;echo&amp;gt;&lt;/span&gt;Generating Documentation with Docco&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;/echo&amp;gt;&lt;/span&gt;
    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;apply&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;executable=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;docco&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;verbose=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;true&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;force=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;true&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;failonerror=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;true&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;
        &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;srcfile&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;/&amp;gt;&lt;/span&gt;
        &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;fileset&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;dir =&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;${src.script.dir}&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;
            &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;include&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;name=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;**/*.coffee&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;/&amp;gt;&lt;/span&gt;
        &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;/fileset&amp;gt;&lt;/span&gt;
    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;/apply&amp;gt;&lt;/span&gt;
&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;/target&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;testing&#34;&gt;Testing&lt;/h3&gt;
&lt;p&gt;I use Jasmine for testing.  &lt;a href=&#34;http://pivotal.github.com/jasmine&#34;&gt;Jasmine&lt;/a&gt; is a &amp;ldquo;Behavior Driven Development&amp;rdquo; style unit testing framework for Javascript.  In an ideal world I would be setting up a build task to run on the server and display the results when I run the build.  Unfortunately I wasn&amp;rsquo;t able to find a way to do that without generating additional dependencies.  Its possible with NodeJS or RequireJS style modules and dependencies, and its also possible using phantomJS, but I didn&amp;rsquo;t want to require either of those for testing.   So instead I have my build task generate an HTML page with the test results.  I may add some scripting to open this page by default after running a production build in the future.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-xml&#34; data-lang=&#34;xml&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;target&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;name=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;test&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;description=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;Generate the JS for testing with Jasmine&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;
  &lt;span style=&#34;color:#6272a4&#34;&gt;&amp;lt;!-- Ideally this would run a server side jasmine test, but that requires better dependency management than we have right now--&amp;gt;&lt;/span&gt;
  &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;echo&amp;gt;&lt;/span&gt;Generating the Test JS with jasmine&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;/echo&amp;gt;&lt;/span&gt;
  &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;apply&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;executable=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;coffee&amp;#34;&lt;/span&gt;  &lt;span style=&#34;color:#50fa7b&#34;&gt;verbose=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;true&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;force=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;true&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;failonerror=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;true&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;parallel=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;true&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;
    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;arg&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;value=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;--compile&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;/&amp;gt;&lt;/span&gt;
    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;arg&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;value=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;--join&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;/&amp;gt;&lt;/span&gt;
    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;arg&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;value=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;${test.output}&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;/&amp;gt;&lt;/span&gt;
    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;srcfile&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;/&amp;gt;&lt;/span&gt;
    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;fileset&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;dir =&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;${test.dir}&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;&lt;/span&gt;
      &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;include&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;name=&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;**/*.coffee&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;/&amp;gt;&lt;/span&gt;
    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;/fileset&amp;gt;&lt;/span&gt;
  &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;/apply&amp;gt;&lt;/span&gt;
&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;/target&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;summary&#34;&gt;Summary&lt;/h3&gt;
&lt;p&gt;Adding a build system has been great for my project.  Its allowed me to be a lot more organized and to do some cool things that are a pain by hand (unit testing, Coffeescript).  I definitely recommend looking into doing this for any non-trivial Javascript/web project that you&amp;rsquo;re working on.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;project name=&amp;quot;scratchcalc&amp;quot; default=&amp;quot;debug&amp;quot;&amp;gt;

  &amp;lt;loadproperties srcfile=&amp;quot;build.properties&amp;quot; /&amp;gt;

  &amp;lt;target name=&amp;quot;debug&amp;quot; depends=&amp;quot;clean, init, copy,concatenatejs&amp;quot;&amp;gt;
    &amp;lt;echo&amp;gt;ScratchCalc Version ${version} (Debug Version)&amp;lt;/echo&amp;gt;
  &amp;lt;/target&amp;gt;

  &amp;lt;target name=&amp;quot;production&amp;quot; depends=&amp;quot;clean, init, copy,concatenatejs,minify,documentation,test&amp;quot;&amp;gt;
    &amp;lt;echo&amp;gt;ScratchCalc Version ${version}&amp;lt;/echo&amp;gt;
  &amp;lt;/target&amp;gt;

  &amp;lt;target name=&amp;quot;copy&amp;quot; description=&amp;quot;Compiles Coffeescript and SASS files,copies the rest&amp;quot;&amp;gt;
    &amp;lt;echo&amp;gt;Copying Coffeescript Files&amp;lt;/echo&amp;gt;
     &amp;lt;copy todir=&amp;quot;${build.dir}&amp;quot;&amp;gt;
      &amp;lt;fileset dir=&amp;quot;${src.dir}&amp;quot; includes=&amp;quot;**/*.HTML,**/*.css,**/*.js&amp;quot; /&amp;gt;
     &amp;lt;/copy&amp;gt;
     &amp;lt;exec executable=&amp;quot;coffee&amp;quot;&amp;gt;
        &amp;lt;arg value=&amp;quot;--compile&amp;quot;/&amp;gt;
        &amp;lt;arg value=&amp;quot;--map&amp;quot; /&amp;gt;
        &amp;lt;arg value=&amp;quot;--output&amp;quot; /&amp;gt;
        &amp;lt;arg value=&amp;quot;${build.script.dir}&amp;quot; /&amp;gt;
        &amp;lt;arg value=&amp;quot;${src.script.dir}&amp;quot; /&amp;gt;
     &amp;lt;/exec&amp;gt;
     &amp;lt;mkdir dir=&amp;quot;${build.styles.dir}&amp;quot; /&amp;gt;
     &amp;lt;apply executable=&amp;quot;sass&amp;quot; dest=&amp;quot;${build.dir}&amp;quot; verbose=&amp;quot;true&amp;quot; force=&amp;quot;true&amp;quot; failonerror=&amp;quot;true&amp;quot;&amp;gt;
          &amp;lt;arg value=&amp;quot;--unix-newlines&amp;quot; /&amp;gt;
          &amp;lt;srcfile /&amp;gt;
          &amp;lt;targetfile /&amp;gt;
          &amp;lt;filelist dir =&amp;quot;${src.dir}&amp;quot; files=&amp;quot;styles/scratch.sass&amp;quot; /&amp;gt;
          &amp;lt;!--&amp;lt;fileset dir=&amp;quot;${src.dir}&amp;quot; includes=&amp;quot;**/*.sass&amp;quot;  /&amp;gt;--&amp;gt;
          &amp;lt;mapper type=&amp;quot;glob&amp;quot; from=&amp;quot;*.sass&amp;quot; to=&amp;quot;*.css&amp;quot;/&amp;gt;
      &amp;lt;/apply&amp;gt;
  &amp;lt;/target&amp;gt;

  &amp;lt;target name=&amp;quot;concatenatejs&amp;quot; description=&amp;quot;Concatenate All the JS together&amp;quot;&amp;gt;
    &amp;lt;!-- Instead of concatenating the JS files directly, use coffee to preserve the source map --&amp;gt;
    &amp;lt;echo&amp;gt;Concatenating the JS&amp;lt;/echo&amp;gt;
    &amp;lt;concat destfile=&amp;quot;${build.libs}&amp;quot;&amp;gt;
       &amp;lt;filelist dir =&amp;quot;${build.script.dir}&amp;quot; files=&amp;quot;lib/jquery.js,lib/knockout.js,lib/BigDecimal.js&amp;quot; /&amp;gt;

        &amp;lt;fileset dir=&amp;quot;${build.script.dir}/lib&amp;quot; includes=&amp;quot;**/*.js&amp;quot;/&amp;gt;
    &amp;lt;/concat&amp;gt;
    &amp;lt;apply executable=&amp;quot;coffee&amp;quot;  verbose=&amp;quot;true&amp;quot; force=&amp;quot;true&amp;quot; failonerror=&amp;quot;true&amp;quot; parallel=&amp;quot;true&amp;quot;&amp;gt;
      &amp;lt;arg value=&amp;quot;--compile&amp;quot; /&amp;gt;
      &amp;lt;arg value=&amp;quot;--map&amp;quot; /&amp;gt;
      &amp;lt;arg value=&amp;quot;--join&amp;quot; /&amp;gt;
      &amp;lt;arg value=&amp;quot;${build.script.output}&amp;quot; /&amp;gt;
      &amp;lt;srcfile /&amp;gt;
      &amp;lt;filelist dir =&amp;quot;${src.script.dir}&amp;quot; files=&amp;quot;...&amp;quot; /&amp;gt;
    &amp;lt;/apply&amp;gt;
  &amp;lt;/target&amp;gt;

  &amp;lt;target name=&amp;quot;documentation&amp;quot; description=&amp;quot;Generate Docco Documentation for coffee files&amp;quot;&amp;gt;
    &amp;lt;echo&amp;gt;Generating Documentation with Docco&amp;lt;/echo&amp;gt;
    &amp;lt;apply executable=&amp;quot;docco&amp;quot; verbose=&amp;quot;true&amp;quot; force=&amp;quot;true&amp;quot; failonerror=&amp;quot;true&amp;quot;&amp;gt;
          &amp;lt;srcfile /&amp;gt;
          &amp;lt;fileset dir =&amp;quot;${src.script.dir}&amp;quot; &amp;gt;
            &amp;lt;include name=&amp;quot;**/*.coffee&amp;quot;/&amp;gt;
          &amp;lt;/fileset&amp;gt;
      &amp;lt;/apply&amp;gt;
  &amp;lt;/target&amp;gt;

  &amp;lt;target name=&amp;quot;test&amp;quot; description=&amp;quot;Generate the JS for testing with Jasmine&amp;quot;&amp;gt;
    &amp;lt;!-- Ideally this would run a server side jasmine test, but that requires better dependency management than we have right now--&amp;gt;
    &amp;lt;echo&amp;gt;Generating the Test JS with jasmine&amp;lt;/echo&amp;gt;
    &amp;lt;apply executable=&amp;quot;coffee&amp;quot;  verbose=&amp;quot;true&amp;quot; force=&amp;quot;true&amp;quot; failonerror=&amp;quot;true&amp;quot; parallel=&amp;quot;true&amp;quot;&amp;gt;
      &amp;lt;arg value=&amp;quot;--compile&amp;quot; /&amp;gt;
      &amp;lt;arg value=&amp;quot;--join&amp;quot; /&amp;gt;
      &amp;lt;arg value=&amp;quot;${test.output}&amp;quot; /&amp;gt;
      &amp;lt;srcfile /&amp;gt;
      &amp;lt;fileset dir =&amp;quot;${test.dir}&amp;quot; &amp;gt;
        &amp;lt;include name=&amp;quot;**/*.coffee&amp;quot;/&amp;gt;
      &amp;lt;/fileset&amp;gt;
    &amp;lt;/apply&amp;gt;
  &amp;lt;/target&amp;gt;

  &amp;lt;target name=&amp;quot;minify&amp;quot; description=&amp;quot;Minify the JS for Production&amp;quot;&amp;gt;
    &amp;lt;echo&amp;gt;Minifying the JS For Production with UglifyJS&amp;lt;/echo&amp;gt;
    &amp;lt;apply executable=&amp;quot;uglifyjs&amp;quot; verbose=&amp;quot;true&amp;quot; force=&amp;quot;true&amp;quot; failonerror=&amp;quot;true&amp;quot;&amp;gt;
          &amp;lt;srcfile /&amp;gt;
          &amp;lt;arg value=&amp;quot;--output&amp;quot; /&amp;gt;
          &amp;lt;arg value=&amp;quot;${build.script.output}&amp;quot; /&amp;gt;
          &amp;lt;filelist  files =&amp;quot;${build.script.output}&amp;quot;/&amp;gt;
      &amp;lt;/apply&amp;gt;
  &amp;lt;/target&amp;gt;

  &amp;lt;target name= &amp;quot;init&amp;quot;&amp;gt;
    &amp;lt;mkdir dir=&amp;quot;${build.dir}&amp;quot; /&amp;gt;
  &amp;lt;/target&amp;gt;

  &amp;lt;target name=&amp;quot;clean&amp;quot;&amp;gt;
    &amp;lt;delete dir=&amp;quot;${build.dir}&amp;quot; /&amp;gt;
  &amp;lt;/target&amp;gt;

&amp;lt;/project&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;Update June 2014: Since writing this post, Javascript based build tools have continued to mature and grow.  These days I&amp;rsquo;d recommend &lt;a href=&#34;http://gruntjs.com/&#34;&gt;Grunt&lt;/a&gt; or &lt;a href=&#34;http://gulpjs.com/&#34;&gt;Gulp&lt;/a&gt; for your front end build script needs, though Ant is still a fine choice if you&amp;rsquo;re integrating your builds with a Java project, or have lots of experience with it.&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&#34;further-reading&#34;&gt;Further Reading&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://www.amazon.com/gp/product/1449327680/ref=as_li_tl?ie=UTF8&amp;camp=1789&amp;creative=390957&amp;creativeASIN=1449327680&amp;linkCode=as2&amp;tag=productjavasc-20&#34;&gt;Maintainable JavaScript&lt;/a&gt;&lt;img src=&#34;http://ir-na.amazon-adsystem.com/e/ir?t=productjavasc-20&amp;l=as2&amp;o=1&amp;a=1449327680&#34; width=&#34;1&#34; height=&#34;1&#34; border=&#34;0&#34; alt=&#34;&#34; style=&#34;border:none !important; margin:0px !important;&#34; /&gt; - This is a great little book for anyone writing Javascript applications in teams.  It has a great section on developing a Javascript build system with Ant&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Coffeescript Is Great</title>
      <link>https://benmccormick.org/2013/02/23/185000.html</link>
      <pubDate>Sat, 23 Feb 2013 19:50:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2013/02/23/185000.html</guid>
      <description>&lt;p&gt;This past week I decided to try and learn more about &lt;a href=&#34;http://coffeescript.org/&#34;&gt;Coffeescript&lt;/a&gt; by converting a side project I&amp;rsquo;ve been working on to use Coffeescript and LESS.  I really enjoyed the experience of working with Coffeescript and hope to use it more in the future. I thought I&amp;rsquo;d share a quick post about my experience, and outline what I see as the advantages and disadvantages.&lt;/p&gt;
&lt;h3 id=&#34;what-is-coffeescript&#34;&gt;What is Coffeescript?&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;http://coffeescript.org/&#34;&gt;Coffeescript&lt;/a&gt; is a programming language with a Ruby-like syntax that compiles transparently into readable, best-practice Javascript.  To break that down:&lt;/p&gt;
&lt;h4 id=&#34;its-a-language-with-ruby-like-syntax&#34;&gt;It&amp;rsquo;s a language with Ruby-like syntax&lt;/h4&gt;
&lt;p&gt;Coffeescript features a short concise syntax with significant whitespace, short operators for many common actions, and syntax that encourages a pseudo-english style of coding.  For instance &lt;code&gt;if empty page then fill page else read page&lt;/code&gt; would be valid syntax for calling a function &lt;code&gt;empty()&lt;/code&gt; on an object &lt;code&gt;page&lt;/code&gt; and then calling the &lt;code&gt;fill&lt;/code&gt; method on it if it was empty or the &lt;code&gt;read&lt;/code&gt; method if it was not.&lt;/p&gt;
&lt;h4 id=&#34;it-compiles-to-readable-best-practice-javascript&#34;&gt;It compiles to readable best-practice Javascript&lt;/h4&gt;
&lt;p&gt;The coffeescript compiler generates Javascript that is easy to read and avoids common pitfalls like unexpected casting with the &lt;code&gt;==&lt;/code&gt; operator.&lt;/p&gt;
&lt;h4 id=&#34;it-compiles-transparently&#34;&gt;It compiles transparently&lt;/h4&gt;
&lt;p&gt;The generated javascript also matches up in a 1-1 relationship with the coffeescript source, so it&amp;rsquo;s still easy to debug and understand what coffeescript is related to the associate Javascript.  I&amp;rsquo;m also excited to try out the &lt;a href=&#34;http://ryanflorence.com/2012/coffeescript-source-maps/&#34;&gt;Coffeescript source maps&lt;/a&gt; for Chrome and bypass this issue completely by debugging directly on the Coffeescript, but haven&amp;rsquo;t had the opportunity to set this up yet.&lt;/p&gt;
&lt;h3 id=&#34;what-i-like-about-coffeescript&#34;&gt;What I like about Coffeescript&lt;/h3&gt;
&lt;h4 id=&#34;its-super-concise&#34;&gt;It&amp;rsquo;s super concise&lt;/h4&gt;
&lt;p&gt;I love writing short code.  Brevity and readability aren&amp;rsquo;t &lt;strong&gt;exactly&lt;/strong&gt; the same thing, but they often overlap, and it&amp;rsquo;s usually easier to debug code when there&amp;rsquo;s less of it, all things being equal.  Coffeescript allows you to write less boilerplate.  An easy example is checking whether an element exists. Compare the JS implementation below to the equivalent Coffeescript.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt;(el &lt;span style=&#34;color:#ff79c6&#34;&gt;!==&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;null&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;typeof&lt;/span&gt; el &lt;span style=&#34;color:#ff79c6&#34;&gt;?==&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;undefined&amp;#39;&lt;/span&gt;){
    &lt;span style=&#34;color:#6272a4&#34;&gt;//do something with el
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-coffeescript&#34; data-lang=&#34;coffeescript&#34;&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; el&lt;span style=&#34;color:#ff79c6&#34;&gt;?&lt;/span&gt;
  &lt;span style=&#34;color:#6272a4&#34;&gt;#do something with el
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;it-doesnt-look-like-java&#34;&gt;It doesn&amp;rsquo;t look like Java&lt;/h4&gt;
&lt;p&gt;This is a bit counterintuitive coming from a guy who learned programming through Java and has never written a line of Ruby, but I think Javascript&amp;rsquo;s &amp;ldquo;Java-like&amp;rdquo; conventions are usually detrimental.  It has curly brace blocks, but not block level scope. It has constructors but not classical inheritance.  It&amp;rsquo;s possible to write valid code that looks exactly like Java in Javascript, and not understand why the behavior is slightly different than you expect.  Coffeescripts syntax feels less likely to lead you down a bad road.&lt;/p&gt;
&lt;h4 id=&#34;it-avoids-the-bad-parts-of-javascript&#34;&gt;It avoids the &amp;ldquo;bad parts&amp;rdquo; of Javascript&lt;/h4&gt;
&lt;p&gt;Javascript has some &amp;ldquo;features&amp;rdquo; that cause more problems than they&amp;rsquo;re worth, including the &lt;code&gt;==&lt;/code&gt; operator, automatic semicolon insertion, and the &lt;code&gt;with&lt;/code&gt; statement.  Coffeescript either avoids these parts completely, or helps the programmer navigate them without having to think about it.  So you can still write your while statements by dropping into normal Javascript code if you must, but Coffeescript won&amp;rsquo;t make it easy.&lt;/p&gt;
&lt;h3 id=&#34;what-i-didnt-like-so-much&#34;&gt;What I didn&amp;rsquo;t like so much&lt;/h3&gt;
&lt;h4 id=&#34;debugging-is-slower&#34;&gt;Debugging is slower&lt;/h4&gt;
&lt;p&gt;While it&amp;rsquo;s certainly much better than it could be due to the transparent compilation, debugging in coffeescript still means that you&amp;rsquo;re debugging a &amp;ldquo;product&amp;rdquo; of your code, not the code itself.  That level of abstraction has a cost.  That cost will vary depending on your experience, code style and tooling (certainly source maps have potential to minimize it), but it will exist, and it needs to be factored in to any language decisions.&lt;/p&gt;
&lt;h4 id=&#34;function-parameters-without-parentheses&#34;&gt;Function Parameters without Parentheses&lt;/h4&gt;
&lt;p&gt;Coffeescript lets you write function parameters without parentheses.  While this allows the cute &lt;strong&gt;sentence-like&lt;/strong&gt; one liners that they demonstrate on their website, in practice I&amp;rsquo;ve found it to really hurt readability.  It&amp;rsquo;s often not clear where the function begins and ends, especially if you&amp;rsquo;re nesting function calls.  Coffeescript is also not consistent in how it applies these rules, because in some cases you DO have to use parentheses.  When declaring a function you must use parentheses if there are 1 or more arguments.  When calling a function you must use parentheses if there are no arguments.    I&amp;rsquo;ve found that I struggle to read function calls if there are more than 1 parameters without parentheses.  As a result I&amp;rsquo;ve used parentheses everywhere there is one or more parentheses, and for now on I&amp;rsquo;m planning on including them even for single param functions just to be consistent.&lt;/p&gt;
&lt;h3 id=&#34;conclusions&#34;&gt;Conclusions&lt;/h3&gt;
&lt;p&gt;I&amp;rsquo;m very glad I tried Coffeescript.  I think it definitely has its place as a concise syntax on top of Javascript that especially makes sense for larger projects where the investment in adjusting to it will pay off over time.  I overall think it adds readability and maintainability from Javascript, though it is by no means perfect in either area.  I&amp;rsquo;m excited to see what happens with this language going forward.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&#34;further-reading&#34;&gt;Further Reading&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;http://ryanflorence.com/2011/case-against-coffeescript/&#34;&gt;The Case Against Coffeescript&lt;/a&gt; - a good roundup of some valid criticisms of Coffeescript, especially with regard to readability&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;http://coffeescript.org/#try:alert%20%22Hello%20CoffeeScript!%22&#34;&gt;Interactive Coffeescript Compiler&lt;/a&gt; - If you want to mess around with Coffeescript, their website has an interactive compiler that translates your Coffeescript to Javascript side by side.  There is also a full tutorial breaking down the languages syntax.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Simple Publish-Subscribe with jQuery</title>
      <link>https://benmccormick.org/2013/02/13/160000.html</link>
      <pubDate>Wed, 13 Feb 2013 17:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2013/02/13/160000.html</guid>
      <description>&lt;p&gt;Here&amp;rsquo;s a cool pattern that I&amp;rsquo;ve been able to use in two of my projects lately:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;//Publish Subscribe with jQuery
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;
&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; exampleHandle &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(){
	&lt;span style=&#34;color:#6272a4&#34;&gt;//do stuff when topic is published
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;	...
}

&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt; subscribe(topic,handle){
    $(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;#subscription&amp;#34;&lt;/span&gt;).bind(topic,handle);
}

&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt; publish(topic,params){
	$(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;#subscription&amp;#34;&lt;/span&gt;).trigger(topic,params)
}

&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt; unsubscribe(topic,handle){
    $(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;#subscription&amp;#34;&lt;/span&gt;).unbind(topic,handle);
}

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;a href=&#34;http://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern&#34;&gt;Publish-Subscribe&lt;/a&gt; is a pretty commonly used model for sending messages in software applications.  Implementations can vary, from the very heavyweight setups of things like &lt;a href=&#34;http://en.wikipedia.org/wiki/Java_Message_Service&#34;&gt;Java Message Service&lt;/a&gt; to much lighter methods.  This is an example of a lightweight pubsub implementation for javascript.&lt;/p&gt;
&lt;h3 id=&#34;implementation-details&#34;&gt;Implementation Details&lt;/h3&gt;
&lt;p&gt;The method is based on jQuery&amp;rsquo;s &lt;code&gt;trigger&lt;/code&gt; and &lt;code&gt;bind&lt;/code&gt; functions.  These allow you to listen for a custom event on an element, and manually trigger an event on an element.  This provides the basic backbone for the simple subscription model.&lt;/p&gt;
&lt;p&gt;If an application element wants to subscribe to a topic, they bind a handler to the &amp;ldquo;subscription element&amp;rdquo;.  This can be a designated element on the page, or just the window element.  You can also of course use different elements for different subscriptions.  Then, when something publishes to that topic, the handler function will execute.&lt;/p&gt;
&lt;p&gt;For publishing, a function can pass a topic and parameters to the publish function.  This calls jQuery&amp;rsquo;s &lt;code&gt;trigger&lt;/code&gt; to set off the event topic, passing along the parameters.  These params are passed to the handle function.&lt;/p&gt;
&lt;p&gt;If an element wants to cancel its subscription, they can pass the topic and handle function to the &lt;code&gt;unsubscribe&lt;/code&gt; method. Note that the handle has to be the same function object that was used to originally subscribe, not a copy or similar function.  You also can use jQuery&amp;rsquo;s &lt;code&gt;unbind&lt;/code&gt; to cancel all subscriptions to a topic by only specifying the topic without the handle function.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve found this to be a useful, lightweight way of creating loosely coupled messages across different components of my software systems.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&#34;further-reading&#34;&gt;Further Reading&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://api.jquery.com/category/events/event-handler-attachment/&#34;&gt;jQuery Documentation&lt;/a&gt; - in depth information on bind, trigger and unbind&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>How I Work:  Refactoring</title>
      <link>https://benmccormick.org/2013/02/03/160000.html</link>
      <pubDate>Sun, 03 Feb 2013 17:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2013/02/03/160000.html</guid>
      <description>&lt;p&gt;I recently took the time to re-examine a section of code that I&amp;rsquo;ve worked on as part of a team for the last year.  Looking at it with fresh eyes I saw plenty of room for improvement.  The issues weren&amp;rsquo;t the result of one bad checkin or poor decision.  Instead they were the result of &amp;ldquo;death by a thousand cuts&amp;rdquo;, a series of small decisions made by different people that were individually justifiable but eventually resulted in brittle, hard to maintain code.&lt;/p&gt;
&lt;p&gt;Over the last few days I&amp;rsquo;ve been taking some time to refactor the code.  Doing so made me think about what questions I should be asking while refactoring code.  Here are a few of the things I look for when I&amp;rsquo;m working to clean up code:&lt;/p&gt;
&lt;h4 id=&#34;does-each-function-do-only-one-thing&#34;&gt;Does each function do only one thing?&lt;/h4&gt;
&lt;p&gt;This has been the hardest bad habit for me to break.  I have a natural inclination when adding new functionality to try to toss it into a related function.  This seems great as first, but its how you go from a function that &amp;ldquo;removes special characters from a string&amp;rdquo;, to one that &amp;ldquo;removes extra characters from a string&amp;rdquo;, to one that &amp;ldquo;processes strings&amp;rdquo;, and finally to &amp;ldquo;the string function&amp;rdquo; that takes a string and returns a new output determined by a glob of unreadable code that nobody understands and everyone is scared to touch.&lt;/p&gt;
&lt;p&gt;Functions that perform only one purpose are easier to understand, easier to use, easier to test, and easier to port to new environments.  When functions start to perform multiple purposes it becomes harder to maintain &lt;a href=&#34;http://en.wikipedia.org/wiki/Don&#39;t_repeat_yourself&#34;&gt;DRY&lt;/a&gt; principles.  If one function performs actions A&amp;amp;B, another performs B&amp;amp;C, and a 3rd one performs A&amp;amp;C, you have to duplicate each action twice, adding code bloat and opening up the risk of inconsistent changes across methods.&lt;/p&gt;
&lt;h4 id=&#34;does-each-objectconcept-have-a-consistent-naming-convention-throughout-the-system&#34;&gt;Does each object/concept have a consistent naming convention throughout the system?&lt;/h4&gt;
&lt;p&gt;One source of frustration I&amp;rsquo;ve had when debugging the code for my project has been the fact that different developers have started different naming conventions for objects within the code.  This results in a single object being called chartObj within function, chart within another, params in another place, and chartData in another instance.  Sometimes these different references even pop up within the same function.  This inconsistency makes it much harder for an unfamiliar developer to understand how the system functions.  This again can lead to duplicating information, if a developer modifying a function or class doesn&amp;rsquo;t realize they already have the information they need.&lt;/p&gt;
&lt;h4 id=&#34;what-assumptions-have-i-made&#34;&gt;What assumptions have I made?&lt;/h4&gt;
&lt;p&gt;One thing that can easily add confusion within a system is making undocumented assumptions.  One common assumption thats made for javascript code is that it will always run in a browser, or have access to a specific library such as jQuery.  While some of these assumptions are necessary, its worthwhile documenting them in some way, either in the comments or through code checks that through exceptions if the assumptions are violated.&lt;/p&gt;
&lt;p&gt;This is important because requirements change.  The particular code that I&amp;rsquo;m working with was originally intended to run only in the browser, without any thought of server-side use.  When a requirement made it necessary to run it with PhantomJS, plenty of changes were needed.  This isn&amp;rsquo;t necessarily problematic, because this particular change was not likely when the original code was made, and the adaptation was not hard.  More problematic was the fact that developers not directly involved with the phantomJS work still were acting under the assumption that the code would run within a browser environment.&lt;/p&gt;
&lt;p&gt;These three questions are obviously not the only things that can be wrong in code, but in my experience they&amp;rsquo;re especially treacherous because they can come in slowly and then make every future change harder.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&#34;further-reading&#34;&gt;Further Reading&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://www.codinghorror.com/blog/2007/03/curlys-law-do-one-thing.html&#34;&gt;Coding Horror: Curly&amp;rsquo;s Law&lt;/a&gt; a readable explanation of DRY principles&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://refactoring.com/&#34;&gt;Refactoring.com&lt;/a&gt;- A nice collection of resources on refactoring by Martin Fowler, who also has written a well regarded &lt;a href=&#34;http://www.amazon.com/gp/product/0201485672/ref=as_li_tl?ie=UTF8&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0201485672&amp;linkCode=as2&amp;tag=productjavasc-20&#34;&gt;book&lt;/a&gt;&lt;img src=&#34;http://ir-na.amazon-adsystem.com/e/ir?t=productjavasc-20&amp;l=as2&amp;o=1&amp;a=0201485672&#34; width=&#34;1&#34; height=&#34;1&#34; border=&#34;0&#34; alt=&#34;&#34; style=&#34;border:none !important; margin:0px !important;&#34; /&gt;
on refactoring.&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Career Fairs: How To Not Get Hired (And How To Give Yourself A Chance)</title>
      <link>https://benmccormick.org/2013/01/25/143000.html</link>
      <pubDate>Fri, 25 Jan 2013 15:30:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2013/01/25/143000.html</guid>
      <description>&lt;p&gt;It was 9:15 and I had just arrived at the gym where the career fair was set to start at 10:00.  Company representatives were setting up their wares in the background and enjoying the provided bagels and coffee, chatting with each other before the rush set to begin at 10.  Arriving at my company&amp;rsquo;s booth, I tossed my bag down and leaned over to fill out a name tag.  As I stood up, I was greeted by a sheet of paper being shoved in my face.  &amp;ldquo;Here is my resume!&amp;rdquo; Bob said as he transferred the paper from my face to my hands.  I was then greeted with a 2 minute monologue explaining why Bob would be the perfect candidate to work for my company.  Eventually I was able to get a word in edgewise, introduce myself, and ask him to come back in 45 minutes when the fair started.  As I walked over to get my much needed bagel, I reflected to myself that Bob would really have to be super impressive to get an interview when he came back to our booth.&lt;/p&gt;
&lt;p&gt;Career Fairs should not be hard.  When recruiters come to a career fair, it is with the sole mission to find students who they can interview for jobs.  When students come to career fairs, they do so to find a company willing to give them a job.  But a lot of the time both sides leave disappointed. I received my first interview for my current company at a career fair, and have now worked at several as a recruiter. There is plenty that can be said about how recruiters can improve in how they reach out to students and other candidates.  But in this post I&amp;rsquo;d like to point out a few simple things that students can do (or not do) to stand out from the crowd and give themselves their best chance for an interview.&lt;/p&gt;
&lt;h4 id=&#34;prepare&#34;&gt;Prepare&lt;/h4&gt;
&lt;p&gt;This is repeated a lot by career counselors, and I think its hard to understand from the student point of view sometimes.  Students think of career fairs as a place to learn about companies.  And thats valid to some extent.  Certainly for younger students its a great way to see what options are out there.  But as a recruiter the first thing I want to know about a student is &amp;ldquo;what type of position are you interested in&amp;rdquo;  If they can&amp;rsquo;t answer that question, no matter how impressive they are, I would be hesitant to give them an interview.&lt;/p&gt;
&lt;p&gt;Preparing for a career fair means knowing what you want, and having at least some idea who might be able to help you get it.  There&amp;rsquo;s fairly little I can do to help a student who comes up to me and asks &amp;ldquo;So do you guys have any jobs that don&amp;rsquo;t involve technology?&amp;rdquo; which is actually probably the most common question we receive.  There&amp;rsquo;s much more that we can say to help a student who comes to us and tells us that they&amp;rsquo;re interested in marketing, or environmental concerns, or really anything else specific.  The second student lets us picture how they could fit in and help our organization, the first student just emphasizes how they don&amp;rsquo;t fit.&lt;/p&gt;
&lt;h4 id=&#34;never-apologize-for-yourself&#34;&gt;Never apologize for yourself&lt;/h4&gt;
&lt;p&gt;This may be the biggest problem that students have communicating with recruiters.  Perhaps because of the perception of a loaded job market, students seem much more aware of how their resumes fall short compared to their peers rather than how they stand out.  Unfortunately they tend to convey this to recruiters rather frequently.  Bob&amp;rsquo;s early morning greeting certainly had its issues, but one thing that he did really well was emphasize what he would bring to our company.&lt;/p&gt;
&lt;p&gt;Something that students fail to understand is that recruiters are usually looking for reasons to like an applicant.  They will take a chance on a candidate with weaknesses on his resume if he or she is genuinely able to show how they can fit into a company.  What is a lot harder to work with is a large assortment of candidates who all have good GPAs, some reasonable experience, and absolutely nothing to differentiate themselves from others.  In an interview setting a student will probably have to explain any weaknesses on their resume.  But a career fair is not an interview.  Its an opportunity to make an impression.  That happens when a student shows that they will bring something positive and useful to the company.&lt;/p&gt;
&lt;h4 id=&#34;take-chances-and-learn-from-your-mistakes&#34;&gt;Take chances, and learn from your mistakes&lt;/h4&gt;
&lt;p&gt;One of the great things about career fairs is that you have the opportunity to instantly apply new lessons you&amp;rsquo;ve learned.  Recruiters don&amp;rsquo;t have some sort of group social network that they&amp;rsquo;re keeping profiles of you on.  If you go to one company&amp;rsquo;s booth and have a bad conversation, that doesn&amp;rsquo;t follow you around to the rest of your interactions with companies unless you let it.  Instead you can learn from your mistakes and hopefully get more comfortable and confident as you get more used to how career fair interactions work.&lt;/p&gt;
&lt;h4 id=&#34;dont-try-to-cheat-the-process&#34;&gt;Don&amp;rsquo;t try to cheat the process&lt;/h4&gt;
&lt;p&gt;Our early morning encounter was not the last I saw of Bob that day.  He came back an hour later and I got to hear another, slightly toned down, explanation of why he would be perfect for my company.  I asked him a few questions and as we wrapped up I told him we would take his resume and be in touch if we were able to offer him an interview.  He asked if I would be able to sign him up for an interview right then.  When I said that I could not, he then asked if he could talk to my coworker who was also recruiting for the same position.  I politely told him that I couldn&amp;rsquo;t stop him, but that I&amp;rsquo;d prefer that he left him free to talk with other candidates, and that I&amp;rsquo;d be happy to answer any more questions he had.  He said that it was fine and walked away.  Five minutes later, I looked over to see my coworker being treated to Bob&amp;rsquo;s full explanation of why he would be a great candidate.&lt;/p&gt;
&lt;p&gt;Assertiveness is in no way a bad thing.  But being able to accept a no and learn from it is also important.  Recruiters will generally be happy to tell a candidate how they could work to be a better candidate for their job, and some may even be willing to meet or exchange emails outside the fair setting to work with a candidate.  If you don&amp;rsquo;t receive an interview, building a relationship can be an even better outcome of meeting with a recruiter at a career fair.  But trying to subvert the system will pretty much guarantee that you end up with neither.  Other examples of this include trying to badger a recruiter for information they&amp;rsquo;ve said they don&amp;rsquo;t know or can&amp;rsquo;t give, talking down other candidates, or (more obviously) lying about your qualifications.&lt;/p&gt;
&lt;h4 id=&#34;pay-attention&#34;&gt;Pay attention&lt;/h4&gt;
&lt;p&gt;I received this advice from a speaker at Carnegie Mellon before I went to the career fair that ended up leading to my first fulltime job.  It turned out to be the best thing he could have said to me.  When you&amp;rsquo;re in line to talk to a recruiter at a career fair, pay attention to the situation.  What type of questions are they asking candidates?  Are they mostly giving information, or trying to ask more interview style questions.  &lt;a href=&#34;http://www.amazon.com/gp/jobs&#34;&gt;Some companies&lt;/a&gt; will even ask technical questions at a career fair, and thats certainly something that you would want to know before you start talking to them.&lt;/p&gt;
&lt;p&gt;In my case by listening I was able to learn that the recruiter I was interviewing was frustrated by the lack of Computer Science candidates he was meeting that day, and particularly frustrated that he was having to turn away qualified international students because he had a limit on how many candidates his company could sponsor for overseas work.  When it was my turn to talk to him I was able to open by telling him that he could &amp;ldquo;accept or reject me on my own merits&amp;rdquo;, and then focused on telling him about my undergraduate computer science degree, with a lesser emphasis on my more management focused graduate program.  As a result I was able to open a personal connection and present myself as an answer to his frustrations,  whereas coming in unaware I may have set myself up as just another student in the wrong degree program who was less of a fit than the international students he was having to send away.&lt;/p&gt;
&lt;h4 id=&#34;dont-forget-that-recruiters-are-human&#34;&gt;Don&amp;rsquo;t forget that recruiters are human&lt;/h4&gt;
&lt;p&gt;The first 5 points all point to this last one.  Preparation is a way of showing recruiters that you value their time.  When you present yourself as meeting a need rather than apologizing, you&amp;rsquo;re helping them solve their problem.  You can take chances at career fairs because recruiters are not automatons blindly picking the best resumes, and relationships and personal interaction actually matter.  You shouldn&amp;rsquo;t cheat the process, because in doing so you&amp;rsquo;re treating other human beings disrespectfully.  And you should pay attention because when you don&amp;rsquo;t you&amp;rsquo;re forgetting that this is a human interaction, and missing out on much of what is involved in it.&lt;/p&gt;
&lt;p&gt;Bob&amp;rsquo;s biggest mistake was forgetting that he was dealing with a human being.  When he approached me in the morning it was with no awareness of my frame of mind or personal preferences.  He was on a mission to get a job.  But he severely sabotaged his efforts by overlooking the human factors of context, mood, and etiquette.  If you can treat a recruiter as a human being, you&amp;rsquo;ll find that they are much more likely to be your ally in getting a job.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Unexpected Javascript: That Doesn&#39;t Do What You Think</title>
      <link>https://benmccormick.org/2013/01/15/183000.html</link>
      <pubDate>Tue, 15 Jan 2013 19:30:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2013/01/15/183000.html</guid>
      <description>&lt;p&gt;When I started writing Javascript, I encountered a lot of stuff that was just plain weird.  Stuff didn&amp;rsquo;t act the way I expected, syntax seemed misleading, and some behavior just seemed completely wrong.  I have a better understanding now and have come to appreciate Javascript for the quirky but stable language that it is once you know the rules.  But just for fun, here are some examples of assumptions that its easy to make when looking at Javascript for the first time.  All of the following statements are wrong (at least in some cases).  See if you know why.  And feel free to contribute more in the comments!&lt;/p&gt;
&lt;h3 id=&#34;equality-problems&#34;&gt;Equality Problems&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0.1+0.2 === .3&lt;/code&gt; is true &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;10000000000000001+20000000000000000 === 300000000000000001&lt;/code&gt; is true &lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;x === x&lt;/code&gt; is true for all values of x &lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;quot;1.0e0&amp;quot; == {valueOf: function(){ return true;}};&lt;/code&gt; is false &lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;if &lt;code&gt;x==y&lt;/code&gt; and &lt;code&gt;x==z&lt;/code&gt; then &lt;code&gt;z==y&lt;/code&gt; &lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;parseInt(&#39;016&#39;) === 16&lt;/code&gt; is true. &lt;sup id=&#34;fnref:6&#34;&gt;&lt;a href=&#34;#fn:6&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;6&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;environment-concerns&#34;&gt;Environment Concerns&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;window&lt;/code&gt; will always be available as a global variable &lt;sup id=&#34;fnref:7&#34;&gt;&lt;a href=&#34;#fn:7&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;7&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;Javascript will always be enabled on your web page &lt;sup id=&#34;fnref:8&#34;&gt;&lt;a href=&#34;#fn:8&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;8&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;If it works in firebug it will work in the browser &lt;sup id=&#34;fnref:9&#34;&gt;&lt;a href=&#34;#fn:9&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;9&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;code-structure&#34;&gt;Code Structure&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;You don&amp;rsquo;t need to add semicolons in javascript, they&amp;rsquo;re inserted automatically &lt;sup id=&#34;fnref:10&#34;&gt;&lt;a href=&#34;#fn:10&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;10&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;I always add semicolons, so I don&amp;rsquo;t need to know about how they&amp;rsquo;re inserted &lt;sup id=&#34;fnref:11&#34;&gt;&lt;a href=&#34;#fn:11&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;11&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;The var keyword is unnecessary, variables are created just by referencing them. &lt;sup id=&#34;fnref:12&#34;&gt;&lt;a href=&#34;#fn:12&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;12&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;return eval(&amp;quot;x&amp;quot;)&lt;/code&gt; is the same as &lt;code&gt;var a = eval; return a(&amp;quot;x&amp;quot;);&lt;/code&gt; &lt;sup id=&#34;fnref:13&#34;&gt;&lt;a href=&#34;#fn:13&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;13&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;Functions are the only thing in Javascript that restrict scope.  &lt;sup id=&#34;fnref:14&#34;&gt;&lt;a href=&#34;#fn:14&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;14&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;function-issues&#34;&gt;Function Issues&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;I will always know what &lt;code&gt;this&lt;/code&gt; is when the function is run &lt;sup id=&#34;fnref:15&#34;&gt;&lt;a href=&#34;#fn:15&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;15&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;You can get the last argument of the function using &lt;code&gt;arguments.pop()&lt;/code&gt; &lt;sup id=&#34;fnref:16&#34;&gt;&lt;a href=&#34;#fn:16&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;16&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;The following will generate different names and alerts for each link: &lt;sup id=&#34;fnref:17&#34;&gt;&lt;a href=&#34;#fn:17&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;17&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt; addLinks () {
  &lt;span style=&#34;color:#ff79c6&#34;&gt;for&lt;/span&gt; (&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; i&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#bd93f9&#34;&gt;0&lt;/span&gt;, link; i&lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#bd93f9&#34;&gt;5&lt;/span&gt;; i&lt;span style=&#34;color:#ff79c6&#34;&gt;++&lt;/span&gt;) {
    link &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;document&lt;/span&gt;.createElement(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;a&amp;#34;&lt;/span&gt;);
    link.innerHTML &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;Link &amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; i;
    link.onclick &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt; () {
        alert(i);
    };
    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;document&lt;/span&gt;.body.appendChild(link);
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;The following function will return 1: &lt;sup id=&#34;fnref:18&#34;&gt;&lt;a href=&#34;#fn:18&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;18&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;(&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt; f(){
    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt; f(){ &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;; }
    &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; f();
    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt; f(){ &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt;; }
  })();
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;The if statement code can be removed here with no side effects: &lt;sup id=&#34;fnref:19&#34;&gt;&lt;a href=&#34;#fn:19&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;19&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt; testf(){
  x&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#bd93f9&#34;&gt;3&lt;/span&gt;;
  &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt;(&lt;span style=&#34;color:#ff79c6&#34;&gt;false&lt;/span&gt;){
    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; x&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#bd93f9&#34;&gt;5&lt;/span&gt;;
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;explanations-here&#34;&gt;Explanations here:&lt;/h4&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;Actually comes to 0.30000000000000004 See &lt;a href=&#34;http://stackoverflow.com/questions/588004/is-javascripts-floating-point-math-broken&#34;&gt;here&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;Loses the trailing 1 due to limits of &lt;a href=&#34;http://stackoverflow.com/questions/588004/is-javascripts-floating-point-math-broken&#34;&gt;floating point numbers&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;It turns out that &lt;code&gt;NaN === NaN&lt;/code&gt; is false&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;Both values get cast to 1 by the &lt;a href=&#34;http://stackoverflow.com/questions/359494/javascript-vs-does-it-matter-which-equal-operator-i-use&#34;&gt;== operator&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:5&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;&#39;&#39; == &amp;lsquo;0&amp;rsquo; is false, 0==&#39;&#39; is true, as is 0 ==&amp;lsquo;0&amp;rsquo;&amp;#160;&lt;a href=&#34;#fnref:5&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:6&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;Prior to ECMAScript 5, strings with leading 0s were interpreted as Octal Notation.  This is resolved in newer browsers, but IE8 and other older browsers still show this behavior.&amp;#160;&lt;a href=&#34;#fnref:6&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:7&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;Window is a browser construct.  It may not be available in all JS environments (for instance, it is not available in Node.js)  Unless you know exactly where your code will be run, be careful&amp;#160;&lt;a href=&#34;#fnref:7&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:8&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;Especially in government situations, security conscious users may disable javascript.  Even if the user is able to enable JS, it may be disabled by default.  You can prepare your site for this.&amp;#160;&lt;a href=&#34;#fnref:8&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:9&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;This is not always accurate.  Firebug executes in eval context, &lt;a href=&#34;http://perfectionkills.com/understanding-delete/&#34;&gt;and that may lead to strange behavior &lt;/a&gt;.&amp;#160;&lt;a href=&#34;#fnref:9&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:10&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;There are some cases when a JS parser may unexpectedly concatenate 2 lines you didn&amp;rsquo;t intend.  This is particularly an issue when the next line begins with an arithmetic operator or a &lt;code&gt;(&lt;/code&gt;, as is the case for immediately invoked function expressions.  You can see an example with &lt;a href=&#34;http://jsfiddle.net/2XSCk/&#34;&gt;this fiddle&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:10&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:11&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;You can still be burned by automatic semicolon insertion even if you don&amp;rsquo;t want to take advantage of it.  The classic example is that Javascript will automatically insert a semicolon after &lt;code&gt;return&lt;/code&gt; if you put the value to be returned on a new line, something that may happen often if you&amp;rsquo;re returning a new object and like to start your curly braces on a new line.&amp;#160;&lt;a href=&#34;#fnref:11&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:12&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;This is more of a beginner assumption.  Undeclared variables are automatically set as global variables and can cause plenty of problems if you don&amp;rsquo;t understand this.&amp;#160;&lt;a href=&#34;#fnref:12&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:13&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;Strangely, Javascript differentiates between direct calls to eval and indirect calls. You can read more on this &lt;a href=&#34;http://stackoverflow.com/questions/9107240/1-evalthis-vs-evalthis-in-javascript&#34;&gt;StackOverflow Question&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:13&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:14&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;This is admittedly an edge case, but catch statements of try&amp;hellip;catch blocks also restrict scope, and the &lt;code&gt;with&lt;/code&gt; statement also modifies the scope, in a different way.  &lt;code&gt;with&lt;/code&gt; is not recommended&amp;#160;&lt;a href=&#34;#fnref:14&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:15&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;Even methods of an object can be called by another object with Javascript&amp;rsquo;s call and apply functions.  The only way to guarantee that the correct value of this is used is to use &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/bind&#34;&gt;Javascript&amp;rsquo;s bind function&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:15&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:16&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;&lt;code&gt;arguments&lt;/code&gt; is not a real array.  It is array-like, in that it has a length value, and has integer properties that it accepts.  But you can&amp;rsquo;t run normal array arguments on it without converting it to an Array object.&amp;#160;&lt;a href=&#34;#fnref:16&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:17&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;This is the classic example of improper closure behavior.  I got this example from &lt;a href=&#34;http://robertnyman.com/2008/10/09/explaining-javascript-scope-and-closures/&#34;&gt;this article&lt;/a&gt;, where you can read more.&amp;#160;&lt;a href=&#34;#fnref:17&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:18&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;Function declarations are hoisted to the top of the function.  Therefore both versions of f are defined, and the second one overrules the first, before f is called and return&amp;#160;&lt;a href=&#34;#fnref:18&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:19&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;More variable hoisting.  In this case the var x declaration is hoisted to the top of the function, even though the assignment can never be executed.  This has the effect of making the variable local to the function rather than global, which is potentially very significant.  You can see the difference in this &lt;a href=&#34;http://jsfiddle.net/H4bCx/&#34;&gt;jsFiddle&lt;/a&gt;/&amp;#160;&lt;a href=&#34;#fnref:19&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>Explaining Javascript: Object Oriented Programming</title>
      <link>https://benmccormick.org/2013/01/11/220500.html</link>
      <pubDate>Fri, 11 Jan 2013 23:05:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2013/01/12/220500.html</guid>
      <description>&lt;p&gt;I&amp;rsquo;m continuing this series on Javascript concepts for people new to the language by looking at  object oriented programming.  One of the more confusing concepts for new Javascript programmers, especially those used to the classical inheritance structures of Java or C++ is Javascript&amp;rsquo;s prototypical inheritance model.  Because it is possible to write syntax for Javascript object creation that can look very similar to classical inheritance in Java, its easy to be misled and have false expectations.  Its important to understand how Javascript&amp;rsquo;s object model works, so that you can adjust your expectations and write code that takes advantage of the language&amp;rsquo;s expressive power.&lt;/p&gt;
&lt;h4 id=&#34;creating-a-new-object&#34;&gt;Creating a new object&lt;/h4&gt;
&lt;p&gt;Javascript provides multiple ways to create new objects.  The simplest way is to just create an empty object with &lt;code&gt;{}&lt;/code&gt;.  The one I&amp;rsquo;ll be looking at today was modeled after Java syntax and gives the language a deceptively classical vibe:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;//Creating Objects with new
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;
    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt; Animal(){
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.home &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;earth&amp;#34;&lt;/span&gt;;
        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.noise &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;roar&amp;#34;&lt;/span&gt;;
    }

    Animal.prototype.sound &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(){
        alert(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.noise);
    }

    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; animalObject &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; Animal();
    animalObject.sound(); &lt;span style=&#34;color:#6272a4&#34;&gt;// roar
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; home &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; animalObject.home &lt;span style=&#34;color:#6272a4&#34;&gt;//earth
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This all looks very familiar and comfortable to a Java programmer.  Animal() is the constructor of a class Animal, with a function sound() and animalObject is an instance of that class.  And you can write code like that if you want.  The problem is, that model is not enforced at all by javascript.  Javascript doesn&amp;rsquo;t have any special &amp;ldquo;constructor functions&amp;rdquo; or classes&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; rel=&#34;footnote&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.  Any function can be used as a constructor&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;//Normal Function as constructor
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;
    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt; normalFunc(){
        alert(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;This is a normal function&amp;#34;&lt;/span&gt;)
    }
    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; normal &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; normalFunc();
    normal &lt;span style=&#34;color:#ff79c6&#34;&gt;instanceof&lt;/span&gt; normalFunc  &lt;span style=&#34;color:#6272a4&#34;&gt;//true
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; x &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; {};
    x.y &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; normalFunc;

    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; huh &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; x.y();
    huh instance &lt;span style=&#34;color:#ff79c6&#34;&gt;of&lt;/span&gt; normalFunc &lt;span style=&#34;color:#6272a4&#34;&gt;//true
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So whats actually happening when you call new before a function?  The new operator generates a new object, binds &lt;code&gt;this&lt;/code&gt; to that object for the constructor function, calls that function and sets that function as the prototype of the new object.  But what is a prototype?&lt;/p&gt;
&lt;h4 id=&#34;prototypes&#34;&gt;Prototypes&lt;/h4&gt;
&lt;p&gt;Javascript inheritance is at its heart &amp;ldquo;prototypical inheritance&amp;rdquo;.  This means that rather than having a concept of &amp;ldquo;classes&amp;rdquo; and &amp;ldquo;implementations&amp;rdquo; of those classes, javascript objects inherit their properties directly from other objects.  So for the &amp;ldquo;classical&amp;rdquo; example above, what is actually happening is that a new object is being created, it is having some of its properties set by the constructor function, and then has the constructor&amp;rsquo;s prototype set as its prototype.  This means that it has access to any properties on the &amp;ldquo;prototype chain&amp;rdquo; of the constructor, which in this case includes the sound method.  All objects have acccess to Object.prototype, giving it access to object properties and methods like toString, hasOwnProperty and others.&lt;/p&gt;
&lt;h4 id=&#34;the-es5-way&#34;&gt;The ES5 Way&lt;/h4&gt;
&lt;p&gt;The ECMAScript 5 specification defines a new way to create objects from existing objects with the &lt;strong&gt;&lt;a href=&#34;https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/create&#34;&gt;Object.create()&lt;/a&gt;&lt;/strong&gt; syntax.  Object.create takes an existing object and sets it as the prototype object for a newly created object&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; rel=&#34;footnote&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;.  This was added to make the syntax for setting the prototype of a new object easier and more clear.&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; rel=&#34;footnote&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;  It also allows us to simulate classical inheritance:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;//ES5 Classical Inheritance example
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;
    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; Cat &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(){
        Animal.call(&lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;); &lt;span style=&#34;color:#6272a4&#34;&gt;//Call the Animal constructor to set local variables
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;        &lt;span style=&#34;color:#ff79c6&#34;&gt;this&lt;/span&gt;.noise &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;meow&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#6272a4&#34;&gt;//override the Animal sound
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    }
    Cat.prototype &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;Object&lt;/span&gt;.create(Animal.prototype)

   &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; kitty &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;new&lt;/span&gt; Cat();

   kitty.sound() &lt;span style=&#34;color:#6272a4&#34;&gt;//meow
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;   alert(kitty.hasOwnProperty(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;sound&amp;#34;&lt;/span&gt;)) &lt;span style=&#34;color:#6272a4&#34;&gt;//false
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;   alert(kitty &lt;span style=&#34;color:#ff79c6&#34;&gt;instanceof&lt;/span&gt; Cat) &lt;span style=&#34;color:#6272a4&#34;&gt;//true
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;   alert(kitty &lt;span style=&#34;color:#ff79c6&#34;&gt;instanceof&lt;/span&gt; Animal) &lt;span style=&#34;color:#6272a4&#34;&gt;//true
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So as you can see, it is very possible to write Object-Oriented Javascript.  The key is to understand that what&amp;rsquo;s happening behind the scenes in Javascript is different than Java or C++, even though the syntax may look similar.&lt;/p&gt;
&lt;h4 id=&#34;summary&#34;&gt;Summary&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Inheritance and object oriented programming in javascript are possible, but are more of a programmer defined construct rather than an inherent property of the language&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Javascript supports prototypical inheritance, meaning that it inherits functions and properties from its prototype object.  All objects inherit from Object.prototype.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ECMAScript 5 introduced support for Object.create, which provides an easier syntax for creating new objects and simulating inheritance.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id=&#34;further-reading&#34;&gt;Further Reading&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://developer.mozilla.org/en-US/docs/JavaScript/Introduction_to_Object-Oriented_JavaScript&#34;&gt;Mozilla&amp;rsquo;s Developer Documentation&lt;/a&gt; has a good summary of implementing Object Oriented Programming concepts in Javascript&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;http://msdn.microsoft.com/en-us/magazine/gg314983.aspx&#34;&gt;Managing Javascript Objects&lt;/a&gt; is a great article by Nicholas Zakas for MSDN about designing an object oriented application in Javascript.  Zakas also has recently written a &lt;a href=&#34;https://leanpub.com/oopinjavascript&#34;&gt;book&lt;/a&gt; on object oriented programming in Javascript&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id=&#34;explaining-javascript&#34;&gt;Explaining Javascript&lt;/h3&gt;
&lt;p&gt;This is the second article in my Explaining Javascript series for introducing Javascript concepts to new JS developers.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;http://www.benmccormick.org/blog/2013/01/08/javascript-explained-closures/&#34;&gt;Closures&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;http://www.benmccormick.org/blog/2013/01/12/javascript-explained-object-oriented-javascript/&#34;&gt;Object Oriented Programming&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;div class=&#34;footnotes&#34;&gt;&lt;ol&gt;
&lt;li class=&#34;footnote&#34; id=&#34;fn:1&#34;&gt;
&lt;p&gt;
In the next version of Javascript ES6 there will be a more formal concept of classes.  You can read more &lt;a href=&#34;http://wiki.ecmascript.org/doku.php?id=strawman:maximally_minimal_classes&#34;&gt;here&lt;/a&gt; if interested
&lt;a href=&#34;#fnref:1&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;li class=&#34;footnote&#34; id=&#34;fn:2&#34;&gt;
&lt;p&gt;
With an optional second argument to set the local properties of the object from another object.  Note that these properties will need to be Objects, not primitive values, or a TypeError will be thrown        
&lt;a href=&#34;#fnref:2&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;li class=&#34;footnote&#34; id=&#34;fn:2&#34;&gt;
&lt;p&gt;Thanks to &lt;a href=&#34;https://plus.google.com/u/0/110077141419510454119/posts&#34;&gt;Eric Elliot&lt;/a&gt; for pointing out that my original description of Object.Create was misleading.  There are multiple ways to create and reuse object code in Javascript.  I only touch on one of them in this article.     &lt;br&gt;
&lt;a href=&#34;#fnref:2&#34; title=&#34;return to article&#34;&gt; ↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Explaining Javascript: Closures</title>
      <link>https://benmccormick.org/2013/01/08/183000.html</link>
      <pubDate>Tue, 08 Jan 2013 19:30:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2013/01/08/183000.html</guid>
      <description>&lt;p&gt;Javascript can be a confusing language when you start to use it.  Designed in a hurry with a functional programming heart and an object oriented skin, Javascript looks a lot like Java or C at first glance.  That expectation causes frustration though when you realize that writing Java style code means that you have no private variables, no block scope, no threads, and no abstract/classes or interfaces.  When I started writing Javascript I had only ever written in pure object oriented languages.  My javascript code was inefficient, fragile, and no fun to write.  I wanted to share some of the things I&amp;rsquo;ve learned since here, to help other people making that adjustment.&lt;/p&gt;
&lt;h3 id=&#34;closures&#34;&gt;Closures&lt;/h3&gt;
&lt;p&gt;Closures are one of the key concepts to understand when you start writing Javascript.  By default, all javascript objects are global, and blocks such as for loops and if statements do not restrict scope.  Closures are Javascript&amp;rsquo;s mechanism for information hiding and controlling scope.  They also allow for some advanced functionality in an elegant way.&lt;/p&gt;
&lt;h4 id=&#34;laying-the-ground&#34;&gt;Laying the ground&lt;/h4&gt;
&lt;p&gt;There are a few things you need to understand about Javascript before closures make sense.&lt;/p&gt;
&lt;h4 id=&#34;functions-are-objects&#34;&gt;Functions are objects&lt;/h4&gt;
&lt;p&gt;Javascript uses First Class Functions, meaning that Functions are Objects in Javascript.  They can be passed to other functions, assigned properties, and be added as properties of another object.  This is very important to understand about Javascript, and a big difference between Javascript and Java/C++.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; f &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(x){
        &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; x&lt;span style=&#34;color:#ff79c6&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt;;
    }
    f(&lt;span style=&#34;color:#bd93f9&#34;&gt;3&lt;/span&gt;);&lt;span style=&#34;color:#6272a4&#34;&gt;//6
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; f2 &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(func, param){
        &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; func(param) &lt;span style=&#34;color:#ff79c6&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;;
    }

    f2(f,&lt;span style=&#34;color:#bd93f9&#34;&gt;5&lt;/span&gt;); &lt;span style=&#34;color:#6272a4&#34;&gt;// 11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;functions-have-their-own-scope&#34;&gt;Functions have their own scope&lt;/h4&gt;
&lt;p&gt;Functions are effectively the only construct in Javascript that can limit scope.  Unlike other languages, code blocks don&amp;rsquo;t automatically limit scope.  So variables defined in for loops and if statements are not confined to those constructs, and Javascript doesn&amp;rsquo;t have an exact equivalent to javascript classes.  Instead functions are used to manage scope.  The key point is that from within a function you can reference variables defined outside the function, but you cannot access variables defined within a function from outside that function.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; a &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;;

    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; f &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(){
        &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; b &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt;;
        alert(a);
        alert(b);
    }
    f();&lt;span style=&#34;color:#6272a4&#34;&gt;// alerts 1, alerts 2
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    a &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;3&lt;/span&gt;;
    f(); &lt;span style=&#34;color:#6272a4&#34;&gt;//alerts 3, alerts 2
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    alert(b) &lt;span style=&#34;color:#6272a4&#34;&gt;// undefined
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;functions-can-be-defined-inside-of-other-functions&#34;&gt;Functions can be defined inside of other functions&lt;/h4&gt;
&lt;p&gt;This naturally follows from the other two points.  Functions are just objects and can be defined anywhere.  So you can define a function inside another function, and use it as the return value of the outer function.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; outer &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(){

        &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; inner &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(x){
            &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; x&lt;span style=&#34;color:#ff79c6&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt;;
        };
        &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; inner;
    };
    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; a &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; outer();

    a(&lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt;); &lt;span style=&#34;color:#6272a4&#34;&gt;// 4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;what-is-a-closure&#34;&gt;What is a Closure?&lt;/h4&gt;
&lt;p&gt;A closure is a function defined inside of another function and returned by that function which maintains a reference to variables in the outer functions scope.  Since the inner function was created within the scope of the outer function, it can reference variables defined within the scope of the outer function.  This is best seen by example.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; outer &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(){
        &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; y &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;3&lt;/span&gt;
        &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; inner &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(x){
            &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; x&lt;span style=&#34;color:#ff79c6&#34;&gt;*&lt;/span&gt;y;
        };
        &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; inner;
    };
    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; triple &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; outer();

    triple(&lt;span style=&#34;color:#bd93f9&#34;&gt;2&lt;/span&gt;); &lt;span style=&#34;color:#6272a4&#34;&gt;// 6;
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    alert(y); &lt;span style=&#34;color:#6272a4&#34;&gt;//undefined
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Since the outer function scope is maintained, you can also use the variables within that class to track state for the function so that it can only be modified through the function.  This is how javascript implements private variables.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; outer &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(){
        &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; y &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;0&lt;/span&gt;
        &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; inner &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;function&lt;/span&gt;(){
            alert(y);
            y&lt;span style=&#34;color:#ff79c6&#34;&gt;++&lt;/span&gt;;
        };
        &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; inner;
    };
    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;var&lt;/span&gt; message &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; outer();
    message() &lt;span style=&#34;color:#6272a4&#34;&gt;// 0
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    message() &lt;span style=&#34;color:#6272a4&#34;&gt;// 1
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    message() &lt;span style=&#34;color:#6272a4&#34;&gt;// 2
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    message() &lt;span style=&#34;color:#6272a4&#34;&gt;// 3
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#6272a4&#34;&gt;//...
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;closures-in-practice&#34;&gt;Closures in practice&lt;/h4&gt;
&lt;p&gt;Closures are one of the most commonly used idioms in javascript.  They&amp;rsquo;re used anytime a programmer wants to protect their implementation of a feature, and prevent other code from directly referencing internal variables.  Its also the key concept in the popular &lt;a href=&#34;http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth&#34;&gt;module pattern&lt;/a&gt;, and many more javascript patterns.  If you are writing javascript of any complexity, or need to understand other people&amp;rsquo;s javascript code, understanding closures is essential.&lt;/p&gt;
&lt;h2 id=&#34;further-reading&#34;&gt;Further Reading&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Closures&#34;&gt;Mozilla Documentation on Closures&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth&#34;&gt;Ben Cherry on the Module Pattern&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.amazon.com/Effective-JavaScript-Specific-Software-Development/dp/0321812182&#34;&gt;Effective Javascript&lt;/a&gt; is a great book for understanding javascript.  I wrote a review of it &lt;a href=&#34;http://benmccormick.org/blog/2013/01/06/book-review-effective-javascript/&#34;&gt;here&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Book Review: Effective Javascript</title>
      <link>https://benmccormick.org/2013/01/06/170000.html</link>
      <pubDate>Sun, 06 Jan 2013 18:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2013/01/06/170000.html</guid>
      <description>&lt;p&gt;&lt;img src=&#34;effectivejs.png&#34; alt=&#34;Effective JS&#34;&gt;&lt;/p&gt;
&lt;p&gt;After seeing some positive early reviews, I went to Amazon last week and bought &amp;ldquo;Effective JavaScript&amp;rdquo; by David Herman.  I&amp;rsquo;m glad that I did.  The book is a great experience for anyone who wants to deepen their understanding of the JavaScript language in a practical grounded fashion.&lt;/p&gt;
&lt;h3 id=&#34;whats-the-book-like&#34;&gt;Whats the book like?&lt;/h3&gt;
&lt;p&gt;The subtitle of the book, &amp;ldquo;68 Specific Ways To Harness The Power Of JavaScript&amp;rdquo;, gives you a hint as to what it will be like.  The book contains 68 best-practice&amp;quot;items&amp;quot;, each an imperative sentence (Prefer Primitives to Object Wrappers, Get comfortable using Higher-Order Functions), divided into 7 chapters (Accustoming yourself to JavaScript, Variable Scope, Objects and Prototypes,  Arrays and Dictionaries, Library and API design, Concurrency).  Each of these items contains an in depth examination of why it is a best practice.  You could read through the table of contents and get something out of the book, but the heart of this book is the way that the author fully digs into each best practice, explaining not only why its a good idea but also what the exception cases are, and why it might be a good idea to break the rule.  The way the discussion of language attributes is grounded by the practical imperative statements, combined with the clear and concise explanations of the author makes everything feel extremely relevant.&lt;/p&gt;
&lt;h3 id=&#34;who-is-the-book-for&#34;&gt;Who is the book for?&lt;/h3&gt;
&lt;p&gt;This is a great book for people who are familiar with JavaScript, and maybe know some of the best practices, but want to deepen their understanding of how the language works and how to use it better.  This is not a comprehensive reference book, or an introductory text for people just starting with Javascript.  I would recommend &lt;a href=&#34;http://www.amazon.com/gp/product/1118026691/ref=as_li_tl?ie=UTF8&amp;camp=1789&amp;creative=390957&amp;creativeASIN=1118026691&amp;linkCode=as2&amp;tag=productjavasc-20&#34;&gt;Professional JavaScript for Web Developers&lt;/a&gt;&lt;img src=&#34;http://ir-na.amazon-adsystem.com/e/ir?t=productjavasc-20&amp;l=as2&amp;o=1&amp;a=1118026691&#34; width=&#34;1&#34; height=&#34;1&#34; border=&#34;0&#34; alt=&#34;&#34; style=&#34;border:none !important; margin:0px !important;&#34; /&gt; and &lt;a href=&#34;http://www.amazon.com/gp/product/0596517742/ref=as_li_tl?ie=UTF8&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0596517742&amp;linkCode=as2&amp;tag=productjavasc-20&#34;&gt;JavaScript: The Good Parts&lt;/a&gt;&lt;img src=&#34;http://ir-na.amazon-adsystem.com/e/ir?t=productjavasc-20&amp;l=as2&amp;o=1&amp;a=0596517742&#34; width=&#34;1&#34; height=&#34;1&#34; border=&#34;0&#34; alt=&#34;&#34; style=&#34;border:none !important; margin:0px !important;&#34; /&gt; respectively for those cases.  This book will increase understanding, not knowledge of the syntax or basics.&lt;/p&gt;
&lt;h3 id=&#34;what-is-good-about-the-book&#34;&gt;What is good about the book?&lt;/h3&gt;
&lt;p&gt;The layered explanations are fantastic.  On the top layer the author gives you the &lt;strong&gt;specific&lt;/strong&gt; best practices, then follows that with an explanation of the underlying reasons for these practices, gives examples of them in action, and following up with any cases where it might be best to use a different method.  The book communicates clearly and concisely about complex subjects.  The payoff is understanding.&lt;/p&gt;
&lt;h3 id=&#34;what-is-not-so-great&#34;&gt;What is not so great?&lt;/h3&gt;
&lt;p&gt;I felt the chapter on Library and API design was significantly weaker than the rest of the book.  Perhaps it&amp;rsquo;s because I&amp;rsquo;m not currently working on building a library, but these chapters felt less like deep explanations and more like quick writeups to justify the stating of the best practices.  The depth of the other explanations was not there.&lt;/p&gt;
&lt;h3 id=&#34;want-to-buy-it&#34;&gt;Want to buy it?&lt;/h3&gt;
&lt;p&gt;Its available on &lt;a href=&#34;http://www.amazon.com/gp/product/0321812182/ref=as_li_tl?ie=UTF8&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0321812182&amp;linkCode=as2&amp;tag=benmccormicko-20&amp;linkId=HOPC6ZNKSVMH3NZ7&#34;&gt;Amazon&lt;/a&gt;&lt;img src=&#34;http://ir-na.amazon-adsystem.com/e/ir?t=benmccormicko-20&amp;l=as2&amp;o=1&amp;a=0321812182&#34; width=&#34;1&#34; height=&#34;1&#34; border=&#34;0&#34; alt=&#34;&#34; style=&#34;border:none !important; margin:0px !important;&#34; /&gt;
.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Sublime Text For Javascript: Packages</title>
      <link>https://benmccormick.org/2013/01/03/160000.html</link>
      <pubDate>Thu, 03 Jan 2013 17:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2013/01/03/160000.html</guid>
      <description>&lt;p&gt;This is the final post in my series on Sublime Text, and how to get the most out of the editor.
The series is focused on Javascript development, as that is how I use Sublime Text, but it
should be applicable to any developer who uses Sublime Text as part of their workflow.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://benmccormick.org/2012/12/30/sublime-text-for-javascript-keyboard-shortcuts&#34;&gt;Sublime Text For Javascript: Keyboard Shortcuts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://benmccormick.org/2013/01/01/sublime-text-for-javascript-configuration&#34;&gt;Sublime Text For Javascript: Configuration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://benmccormick.org/2013/01/03/sublime-text-for-javascript-plugins&#34;&gt;Sublime Text For Javascript: Packages&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A large part of Sublime Text&amp;rsquo;s power comes from its extensive collection of packages.
There are packages for pretty much every use case.  I&amp;rsquo;m going to limit myself to listing 5 of the most useful for Javascript development, but its definitely worth looking around at the options to find more that fit what you want to do.&lt;/p&gt;
&lt;h3 id=&#34;1-package-control---the-essential-plugin&#34;&gt;#1. Package Control - The Essential Plugin&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;http://wbond.net/sublime_packages/package_control&#34;&gt;Package Control&lt;/a&gt; is the very first package anyone should install for Sublime Text.  It makes it easy to install any other package without having to clone Git repositories or work through Sublimes file structure.  And the author has made it relatively easy to install Package control as well.  All that is required is a quick copy and paste of code provided on the developers website.  Package control makes it easy to install new packages, snippets, themes, and color schemes.&lt;/p&gt;
&lt;h3 id=&#34;2-sublime-linter---write-better-code&#34;&gt;#2. Sublime Linter - Write Better Code&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/SublimeLinter/SublimeLinter&#34;&gt;Sublime Linter&lt;/a&gt; is a code quality tool for Sublime Text that makes it easy to find and fix code that doesn&amp;rsquo;t meet the standards that you define.  For javascript code you can choose to use jsHint&lt;a href=&#34;http://www.jshint.com/&#34;&gt;jshint&lt;/a&gt; or jsLint&lt;a href=&#34;http://www.jslint.com/&#34;&gt;jslint&lt;/a&gt;, the two most popular javascript linters.  I highly recommend this package.  It places a border around lines that are non-conformant with a message in the bottom border of the editor, but otherwise stays out of your way.  It makes it easy to fix code issues as you&amp;rsquo;re editing, rather than waiting till the end and getting a huge error dump when you run your code through the linter.&lt;/p&gt;
&lt;h3 id=&#34;3-emmet---get-through-the-boilerplate&#34;&gt;#3. Emmet - Get Through The Boilerplate&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;http://docs.emmet.io/&#34;&gt;Emmet&lt;/a&gt; is a tool for web developers that allows you to use CSS style prefixes to quickly generate html code.  It allows quick generation of boilerplate HTML with a familiar syntax, so you can focus on code instead of markup.  The github project for the package is &lt;a href=&#34;https://github.com/sergeche/emmet-sublime&#34;&gt;here&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;4-git---take-control-of-your-project-inside-your-editor&#34;&gt;#4. Git - Take Control Of Your Project Inside Your Editor&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;http://git-scm.com/&#34;&gt;Git&lt;/a&gt; has rapidly become the go to version control system for open-source projects, and is also used by many private organizations and individual developers.  If you&amp;rsquo;re using Git to manage your javascript projects, you should definitely install the &lt;a href=&#34;https://github.com/kemayo/sublime-text-2-git/wiki&#34;&gt;git package&lt;/a&gt; for Sublime Text.  Its not a command line replacement, some commands move much slower than it would with command line, but it allows the convenience of using common commands like add, diff, and blame from within your editor.&lt;/p&gt;
&lt;h3 id=&#34;5-clipboard-history---improve-your-clipboard&#34;&gt;#5. Clipboard History - Improve your clipboard&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/kemayo/sublime-text-2-clipboard-history&#34;&gt;Clipboard History&lt;/a&gt;  is a nice little utility that lets you see the recent history of your clipboard.  It only works for snippets copied from within Sublime Text, but its a nice little tool for refactoring, when you&amp;rsquo;re moving code around quickly and want to delete something without losing it completely.&lt;/p&gt;
&lt;h3 id=&#34;find-your-own&#34;&gt;Find your own&lt;/h3&gt;
&lt;p&gt;In the end different packages work for different people.  I highly recommend installing Package Control and browsing around through the options.  If you find a great package, leave a comment here and let me know.  There are a lot of packages out there, and everybody&amp;rsquo;s needs are different&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Sublime Text For Javascript: Configuration</title>
      <link>https://benmccormick.org/2013/01/01/130000.html</link>
      <pubDate>Tue, 01 Jan 2013 14:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2013/01/01/130000.html</guid>
      <description>&lt;p&gt;I&amp;rsquo;m starting a new series of posts on Sublime Text, and how to get the most out of the editor.
The series will be focused on Javascript development, as that is how I use Sublime Text, but it should be applicable to any developer who uses Sublime Text as part of their workflow.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://benmccormick.org/2012/12/30/sublime-text-for-javascript-keyboard-shortcuts&#34;&gt;Sublime Text For Javascript: Keyboard Shortcuts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://benmccormick.org/2013/01/01/sublime-text-for-javascript-configuration&#34;&gt;Sublime Text For Javascript: Configuration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://benmccormick.org/2013/01/03/sublime-text-for-javascript-plugins&#34;&gt;Sublime Text For Javascript: Packages&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;configuration&#34;&gt;Configuration&lt;/h3&gt;
&lt;p&gt;Sublime Text allows for plenty of text editing power out of the box, but the real power comes
when you begin configuring it to meet your own needs.  This is by definition a topic that different people will approach in different ways, but in this post I will attempt to give an overview of what is configurable in Sublime Text (&lt;strong&gt;Spoiler: almost everything&lt;/strong&gt;), and how to configure them.&lt;/p&gt;
&lt;h3 id=&#34;the-basics&#34;&gt;The Basics&lt;/h3&gt;
&lt;p&gt;Sublime Text settings are defined using json files.  There are multiple levels of configuration
to give you very fine grained control of how your editor will act for different files.
From the &lt;a href=&#34;http://www.sublimetext.com/docs/2/settings.html&#34;&gt;Sublime Docs&lt;/a&gt;,  settings are prioritized like this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Settings files are consulted in this order:&lt;/p&gt;
&lt;p&gt;Packages/Default/Preferences.sublime-settings
Packages/Default/Preferences (platform).sublime-settings
Packages/User/Preferences.sublime-settings
&amp;lt;Project Settings &amp;gt;
Packages/ &amp;lt;syntax &amp;gt; / &amp;lt;syntax &amp;gt;.sublime-settings
Packages/User/&amp;lt;syntax &amp;gt;.sublime-settings
&amp;lt;Buffer Specific Settings &amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Settings can be set on a default, user, project, or syntax-type basis, and add specific
settings for distraction free mode.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Never set your options using the Default-Settings files!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The default settings files for Sublime text will be overwritten when you update
to a new version, and the plugin specific settings will be overwritten when those
plugins are updated.  Always use the &amp;ldquo;User-Settings&amp;rdquo; files instead for &amp;ldquo;global&amp;rdquo;
settings.  Its not a bad idea to immediately copy the default settings file to
the User-Settings file when you&amp;rsquo;re initially setting up sublime so that you can
see all of the options that are set in that file and edit them accordingly.&lt;/p&gt;
&lt;p&gt;Heres my User-Settings file for my Windows-based version of Sublime:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;{
    &lt;span style=&#34;color:#6272a4&#34;&gt;// Modified Solarized Theme with Mardown Support (https://gist.github.com/1904917)
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;   &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;color_scheme&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;Packages/User/Solarized (Light).tmTheme&amp;#34;&lt;/span&gt;,

    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;font_face&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;Consolas&amp;#34;&lt;/span&gt;,
    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;font_size&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#bd93f9&#34;&gt;8&lt;/span&gt;,

    &lt;span style=&#34;color:#6272a4&#34;&gt;// Valid options are &amp;#34;no_bold&amp;#34;, &amp;#34;no_italic&amp;#34;, &amp;#34;no_antialias&amp;#34;, &amp;#34;gray_antialias&amp;#34;,
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#6272a4&#34;&gt;// &amp;#34;subpixel_antialias&amp;#34;, &amp;#34;no_round&amp;#34; (OS X only) and &amp;#34;directwrite&amp;#34; (Windows only)
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;font_options&amp;#34;&lt;/span&gt;: [&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;directwrite&amp;#34;&lt;/span&gt;],

    &lt;span style=&#34;color:#6272a4&#34;&gt;// If enabled, will highlight any line with a caret
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;highlight_line&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ff79c6&#34;&gt;true&lt;/span&gt;,

    &lt;span style=&#34;color:#6272a4&#34;&gt;// Set to true to automatically save files when switching to a different file
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#6272a4&#34;&gt;// or application
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;save_on_focus_lost&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ff79c6&#34;&gt;true&lt;/span&gt;,

    &lt;span style=&#34;color:#6272a4&#34;&gt;// Columns in which to display vertical rulers
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;rulers&amp;#34;&lt;/span&gt;:
    [
        &lt;span style=&#34;color:#bd93f9&#34;&gt;80&lt;/span&gt;
    ],

    &lt;span style=&#34;color:#6272a4&#34;&gt;// The theme controls the look of Sublime Text&amp;#39;s UI (buttons, tabs, scroll bars, etc)
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;theme&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;Soda Light.sublime-theme&amp;#34;&lt;/span&gt;,

    &lt;span style=&#34;color:#6272a4&#34;&gt;// Set to true to close windows as soon as the last file is closed, unless
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#6272a4&#34;&gt;// there&amp;#39;s a folder open within the window. This is always enabled on OS X,
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#6272a4&#34;&gt;// changing it here won&amp;#39;t modify the behavior.
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;close_windows_when_empty&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ff79c6&#34;&gt;true&lt;/span&gt;,

    &lt;span style=&#34;color:#6272a4&#34;&gt;// List any packages to ignore here. When removing entries from this list,
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#6272a4&#34;&gt;// a restart may be required if the package contains plugins.
&lt;/span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;ignored_packages&amp;#34;&lt;/span&gt;:
    [
        &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;Default&amp;#34;&lt;/span&gt;,
        &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;Vintage&amp;#34;&lt;/span&gt;,
        &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;ZenCoding&amp;#34;&lt;/span&gt;
    ]
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;visuals&#34;&gt;Visuals&lt;/h3&gt;
&lt;p&gt;One of the most configurable thing about Sublime Text is the GUI.  If you don&amp;rsquo;t
like something about how the program looks, it is probably configurable. Some of the
most important visual settings are below:&lt;/p&gt;
&lt;h4 id=&#34;color-scheme&#34;&gt;Color Scheme&lt;/h4&gt;
&lt;p&gt;The most obvious configurable visual setting is the color scheme.  Sublime ships
with a solid selection of default color schemes, and its easy to find and download
more online with &lt;a href=&#34;http://wbond.net/sublime_packages/package_control&#34;&gt;Package Control&lt;/a&gt;, which I&amp;rsquo;ll cover more in the
plugins article.  I use Sublime&amp;rsquo;s Monokai Bright theme for JS development, and a
&lt;a href=&#34;https://gist.github.com/1904917&#34;&gt;custom Solarized theme&lt;/a&gt; for writing in Markdown for this blog and my
notes.  You can set color scheme with a command like this in one of your settings files&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;color_scheme&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;Packages/User/Solarized (Light).tmTheme&amp;#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;or you can set it in the preferences menu on the top of the screen (this will set it
in your User-Settings file)&lt;/p&gt;
&lt;h4 id=&#34;theme&#34;&gt;Theme&lt;/h4&gt;
&lt;p&gt;You can also configure the overall look and feel of the application.  While the
default is by no means ugly, many people prefer the &lt;a href=&#34;https://github.com/buymeasoda/soda-theme/&#34;&gt;Soda&lt;/a&gt; theme that adds
some prettier gradients and a choice of a light/dark theme.  You can set that
like this after downloading the theme:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;theme&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;Soda Light.sublime-theme&amp;#34;&lt;/span&gt;,
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;quickies&#34;&gt;Quickies&lt;/h4&gt;
&lt;p&gt;Here are a few more quick visual tweaks&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;ldquo;rulers&amp;rdquo;: set where to show vertical rulers.  Takes an array of integers.  I put one at 80 in order to limit my line lengths in javascript.&lt;/li&gt;
&lt;li&gt;&amp;ldquo;tab_size&amp;rdquo;,&amp;ldquo;translate_tabs_to_spaces&amp;rdquo;, and &amp;ldquo;use_tab_stops: Determine space and tabs behaviors.&lt;/li&gt;
&lt;li&gt;&amp;ldquo;highlight_line&amp;rdquo;: If true will highlight every line with a cursor&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;key-bindings&#34;&gt;Key Bindings&lt;/h3&gt;
&lt;p&gt;This is where all of the information from &lt;a href=&#34;http://benmccormick.org/2012/12/30/sublime-text-for-javascript-keyboard-shortcuts&#34;&gt;Monday&amp;rsquo;s post&lt;/a&gt; starts to become a whole lot less useful.  All of the keyboard shortcuts that were discussed in that post are completely configurable.  Again you want to use the &amp;ldquo;User&amp;rdquo; preferences file in
Packages/User to set the keybindings.  Keybindings are stored in json form like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;{ &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;keys&amp;#34;&lt;/span&gt;: [&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;ctrl+z&amp;#34;&lt;/span&gt;], &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;command&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;undo&amp;#34;&lt;/span&gt; },
{ &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;keys&amp;#34;&lt;/span&gt;: [&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;ctrl+shift+z&amp;#34;&lt;/span&gt;], &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;command&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;redo&amp;#34;&lt;/span&gt; },
{ &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;keys&amp;#34;&lt;/span&gt;: [&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;ctrl+y&amp;#34;&lt;/span&gt;], &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;command&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;redo_or_repeat&amp;#34;&lt;/span&gt; },
{ &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;keys&amp;#34;&lt;/span&gt;: [&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;ctrl+u&amp;#34;&lt;/span&gt;], &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;command&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;soft_undo&amp;#34;&lt;/span&gt; },
{ &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;keys&amp;#34;&lt;/span&gt;: [&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;ctrl+shift+u&amp;#34;&lt;/span&gt;], &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;command&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;soft_redo&amp;#34;&lt;/span&gt; },
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You can override existing shortcuts to make common commands more convenient or
create your own by combining &lt;a href=&#34;http://www.sublimetext.com/docs/commands&#34;&gt;sublime commands&lt;/a&gt;.  One cool trick is the ability to define keyboard shortcuts to toggle settings.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The toggle_setting command can be used to toggle a setting. For example, to make a key binding that toggles the word_wrap setting on the current file, you can use (in Preferences/Key Bindings - User):&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;{
    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;keys&amp;#34;&lt;/span&gt;: [&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;alt+w&amp;#34;&lt;/span&gt;],
    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;command&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;toggle_setting&amp;#34;&lt;/span&gt;,
    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;args&amp;#34;&lt;/span&gt;:
    {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;setting&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;word_wrap&amp;#34;&lt;/span&gt;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;The set_setting command can be used to set a setting to a specific value. For example, this key binding makes the current file use the Cobalt color scheme:&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;{
    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;keys&amp;#34;&lt;/span&gt;: [&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;ctrl+k&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;ctrl+c&amp;#34;&lt;/span&gt;],
    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;command&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;set_setting&amp;#34;&lt;/span&gt;,
    &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;args&amp;#34;&lt;/span&gt;:
    {
        &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;setting&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;color_scheme&amp;#34;&lt;/span&gt;,
        &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;#34;value&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;Packages/Color Scheme - Default/Cobalt.tmTheme&amp;#34;&lt;/span&gt;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The settings modified here are buffer specific settings: they override any settings placed in a settings file, but apply to the current file only.&lt;/p&gt;
&lt;h3 id=&#34;plugins&#34;&gt;Plugins&lt;/h3&gt;
&lt;p&gt;Plugins also sometimes have their own configuration files.  These generally mimic the format of the editor, and its adviced as usual to use the User Settings for these so as to avoid having your settings blown away with updates&lt;/p&gt;
&lt;h3 id=&#34;build-systems&#34;&gt;Build Systems&lt;/h3&gt;
&lt;p&gt;Sublime also lets you configure custom build systems to build your project.  These can be defined at the same levels of everything else, though in this case it probably makes most sense at the syntax and project level.&lt;/p&gt;
&lt;h3 id=&#34;projects&#34;&gt;Projects&lt;/h3&gt;
&lt;p&gt;Projects are a great way to organize your Sublime Text files.  You can set up a project
at any time by creating a .sublime-project file (this will happen automatically if you choose save project or edit project in the Project toolbar menu).  The project configuration menu takes a list of folders, a list of settings, and a list of build system settings as a JSON file.  These settings will then override your user level settings for files in the folders that you specify.  This lets you meet project specifications for things like tabs or line length without constantly fiddling with settings.  You also can enable or disable different plugins based on project, and create visual distinction between projects with different color themes.&lt;/p&gt;
&lt;h3 id=&#34;macros&#34;&gt;Macros&lt;/h3&gt;
&lt;p&gt;Macros let you save a series of common commands as a json file.  You can then run them
from the &amp;ldquo;Tools/Macro&amp;rdquo; menu.  There&amp;rsquo;s more information in the &lt;a href=&#34;http://docs.sublimetext.info/en/latest/extensibility/macros.html&#34;&gt;unofficial docs&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;snippets&#34;&gt;Snippets&lt;/h3&gt;
&lt;p&gt;One final thing that you can configure in Sublime Text is &amp;ldquo;Snippets&amp;rdquo;.  Sublime Snippets provide advanced templating ability thats configured with an XML template.  A detailed description of what you can do with snippets is available in the &lt;a href=&#34;http://docs.sublimetext.info/en/latest/extensibility/snippets.html&#34;&gt;unofficial docs&lt;/a&gt;.  Suffice it to say that it allows everything from a simple text replacement to full  templating based on a variety of environment variables.&lt;/p&gt;
&lt;p&gt;Sublime contains several Javascript related snippets by default for several basic tasks, and there are more that you can find in other places around the internet.  &lt;a href=&#34;http://freshbrewedcode.com/jonathancreamer/2012/07/13/a-couple-of-useful-javascript-sublime-text-2-snippets/&#34;&gt;Here&amp;rsquo;s one example by Jonathan Creamer&lt;/a&gt; with a few snippets for plugin development, and a nice little console.log snippet for quick development.&lt;/p&gt;
&lt;h3 id=&#34;summary&#34;&gt;Summary&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Pretty much everything in Sublime can be customized using JSON files&lt;/li&gt;
&lt;li&gt;Use User files or project/syntax specific files, not the Default files&lt;/li&gt;
&lt;li&gt;Learn your options and you can get a lot more out of Sublime Text&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I hope this is helpful.  I&amp;rsquo;ll be following up with one final post later this week on helpful Sublime plugins for javascript development.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Sublime Text For Javascript: Keyboard Shortcuts</title>
      <link>https://benmccormick.org/2012/12/30/160000.html</link>
      <pubDate>Sun, 30 Dec 2012 17:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2012/12/30/160000.html</guid>
      <description>&lt;p&gt;I&amp;rsquo;m starting a new series of posts on Sublime Text, and how to get the most out of the editor.
The series will be focused on Javascript development, as that is how I use Sublime Text, but it
should be applicable to any developer who uses Sublime Text as part of their workflow.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://benmccormick.org/2012/12/30/sublime-text-for-javascript-keyboard-shortcuts&#34;&gt;Sublime Text For Javascript: Keyboard Shortcuts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://benmccormick.org/2013/01/01/sublime-text-for-javascript-configuration&#34;&gt;Sublime Text For Javascript: Configuration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://benmccormick.org/2013/01/03/sublime-text-for-javascript-plugins&#34;&gt;Sublime Text For Javascript: Packages&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;keyboard-shortcuts&#34;&gt;Keyboard Shortcuts&lt;/h2&gt;
&lt;p&gt;&lt;img src=&#34;Sublime_cheat_sheet.png&#34; alt=&#34;Keyboard Shortcuts&#34;&gt;&lt;/p&gt;
&lt;h5 id=&#34;update-get-a-printable-cheat-sheet-herehttpsgithubcomben336benmccormick_blog_postsblobmasterimagespost_imagessublime_cheatsheetpdfrawtrue&#34;&gt;Update: Get a &lt;a href=&#34;https://github.com/ben336/benmccormick_blog_posts/blob/master/images/post_images/sublime_cheatsheet.pdf?raw=true&#34;&gt;printable cheat sheet here&lt;/a&gt;)&lt;/h5&gt;
&lt;p&gt;When you&amp;rsquo;ve gotten comfortable with a quality text editor, it should really be unnecessary to
move your hands off the keyboard. Sublime Text gives you a ton of power without ever touching
your mouse.  It takes a little while to get up to speed with its way of doing things, but the
more you use these shortcuts, the more you want to use Sublime Text.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note: I will be using windows based commands for these examples.  In general they are the same for linux, and similar for OSX, with command replacing ctrl, and alt replacing shift in some cases.&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&#34;navigation&#34;&gt;Navigation&lt;/h3&gt;
&lt;h4 id=&#34;ctrl--p--go-to-anything&#34;&gt;Ctrl + P  (Go To Anything)&lt;/h4&gt;
&lt;p&gt;We&amp;rsquo;re starting with the best here.  Ctrl + P opens up &amp;ldquo;Go To Anything&amp;rdquo;.  This allows for
fuzzy search with Google Instant style results from among all open files and files in your current project.&lt;/p&gt;
&lt;p&gt;So you could start typing &amp;ldquo;mpag&amp;rdquo; and the editor would instantly load up mainPage.html into your editor pane, while showing a list of possible hits in your command palette, with a score next to them showing the confidence level of the match.  The speed of this feature is amazing.&lt;/p&gt;
&lt;p&gt;The real power of Go To Anything though comes when you combine it with subcommands.
Go To Anything supports 3 subcommands&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;@&lt;/strong&gt; - this lets you specify a function within the file that you want to go to.  This can
also be fuzzy-matched, so chb@setbg might take you immediately to the setBackground
method of the chartbuilder.js file.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;:&lt;/strong&gt; - this lets you go to a line by number.  So chb:100 will take you to line 100 of chartbuilder.js&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;#&lt;/strong&gt; - this lets you search for a string in the file so chb#extend will take you to
the first occurence of &amp;ldquo;extend&amp;rdquo; in Chartbuilder.js.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can also use these subcommands by themselves (Ctrl+ subcommand) to navigate within the current file.&lt;/p&gt;
&lt;p&gt;After you&amp;rsquo;ve found the location you want, you can hit enter and begin editing immediately.&lt;/p&gt;
&lt;h4 id=&#34;ctrl--alt--p-switch-project&#34;&gt;Ctrl + alt + P (Switch Project)&lt;/h4&gt;
&lt;p&gt;Sublime Projects are a powerful way to organize your work.  Switching projects allows
you to instantly open all windows that you had left open the last time you used the project.
This gives you the ability to instant switch between work-items without losing momentum
getting things set up the way you want.  ctrl + alt + P lets you switch projects within
your current window.&lt;/p&gt;
&lt;h4 id=&#34;ctrl--shift--p-command-palette&#34;&gt;Ctrl + shift + P (Command Palette)&lt;/h4&gt;
&lt;p&gt;Sublime&amp;rsquo;s Command Palette probably deserves its own article.  But in essence this
is the easiest way to control plugins, and also holds shortcuts for several of the lesser used
commands like setting syntax and controlling bookmarks.&lt;/p&gt;
&lt;h4 id=&#34;ctrl--pgup-ctrl--pgdown-switch-files&#34;&gt;Ctrl + PgUp, Ctrl + PgDown (Switch Files)&lt;/h4&gt;
&lt;p&gt;These let you switch between your open files.  There are also Ctrl+tab and Ctrl+shift+tab, which are listed as
next file in stack and previous file in stack.  I have seen no difference between the behavior of these two
sets of commands.  If anybody knows the difference, please enlighten me in the comments.&lt;/p&gt;
&lt;h4 id=&#34;f2-and-variants-bookmark-commands&#34;&gt;F2 and variants (Bookmark Commands)&lt;/h4&gt;
&lt;p&gt;Sublime Texts bookmarks make it easy to move to predetermined locations in the file.  Bookmarks are set to a specific location in the file. There are several shortcuts associated with them.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Ctrl + F2&lt;/strong&gt; - Toggles a bookmark from the current location.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;F2&lt;/strong&gt; - Go to next bookmark&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Shift + F2&lt;/strong&gt; - Go to previous bookmark&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Alt + F2&lt;/strong&gt; - puts a cursor at each bookmark location&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ctrl + Shift + F2&lt;/strong&gt; - Clear all bookmarks&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;search-commands&#34;&gt;Search Commands&lt;/h4&gt;
&lt;p&gt;Sublime Text has a fairly standard set of search commands, with a few special twists&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Ctrl + F&lt;/strong&gt; - Search&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ctrl + Shift + F&lt;/strong&gt; - Search in other files (gives a listing of all findings in a new file, you can use f4 to iterate over the results within their files)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;F3&lt;/strong&gt; - Find Next&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Shift + F3&lt;/strong&gt; - Find Previous&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ctrl + H&lt;/strong&gt; - Replace&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ctrl + E&lt;/strong&gt; - Search for current selection&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;a-few-more-minor-shortcuts&#34;&gt;A few more minor shortcuts&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Ctrl + M&lt;/strong&gt; - Go to a matching bracket.  Goes to the end of the innermost set of brackets if not currently on a bracket.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ctrl + K then Ctrl + C&lt;/strong&gt; - Scrolls to move cursor to center of the screen&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;selection-and-multiple-cursors&#34;&gt;Selection and Multiple Cursors&lt;/h3&gt;
&lt;p&gt;One of the most powerful features of Sublime Text is its ability to easily select and manipulate text, especially
the way it can use multiple cursors simultaneously&lt;/p&gt;
&lt;h4 id=&#34;ctrl--d-multiple-selection&#34;&gt;Ctrl + D (Multiple Selection)&lt;/h4&gt;
&lt;p&gt;One of the cooler features of sublime text is its multiple selection option.  When you have some selected text,
entering Ctrl+D selects the next instance of that selection.  You can do this repeatedly.  If you want to skip an instance
you can just hit Ctrl + K and then Ctrl + D again.  You can then edit all of the selections together, or use the multiple selections to make further changes.  The Esc key lets you go back to a single selection.&lt;/p&gt;
&lt;h4 id=&#34;ctrl--l-select-line&#34;&gt;Ctrl + L (Select Line)&lt;/h4&gt;
&lt;p&gt;I use this one all the time.  Allows you to select the entire line the cursor is on.  Combined with Ctrl + D you can select
every line a selection appears on.&lt;/p&gt;
&lt;h4 id=&#34;ctrl--shift--l-split-selection-into-lines&#34;&gt;Ctrl + Shift + L (Split Selection into lines)&lt;/h4&gt;
&lt;p&gt;Splits a multiline selection into individual line selections, giving you a cursor for each line&lt;/p&gt;
&lt;h4 id=&#34;ctrl--alt--updown-add-a-new-line-with-a-cursor&#34;&gt;Ctrl + alt + Up/Down (Add a new line with a cursor)&lt;/h4&gt;
&lt;p&gt;Adds a new line above or below the current line with an additional cursor at that line.
Lets you quickly start multiple lines with the same content&lt;/p&gt;
&lt;h4 id=&#34;ctrl--d-select-current-word&#34;&gt;Ctrl + D Select Current Word&lt;/h4&gt;
&lt;p&gt;Expands the selection to the current word&lt;/p&gt;
&lt;h4 id=&#34;ctrl--shift--space---expand-selection-to-current-block&#34;&gt;Ctrl + Shift + Space - Expand selection to current block&lt;/h4&gt;
&lt;p&gt;The name of this feature in Sublime Text is &amp;ldquo;Expand selection to current scope&amp;rdquo;,
but thats misleading for javascript, which does not have block scope.  There are
a few more of these commands, but this and Ctrl + Shift + M (which appears to behave identically)
are the relevant commands for Javascript.  Ctrl + Shift + A expands to tag for HTML.&lt;/p&gt;
&lt;h3 id=&#34;editing&#34;&gt;Editing&lt;/h3&gt;
&lt;h4 id=&#34;ctrl---add-comment&#34;&gt;Ctrl + / (Add Comment)&lt;/h4&gt;
&lt;p&gt;If you add a shift it makes a block comment.&lt;/p&gt;
&lt;h4 id=&#34;ctrl--enter-move-to-a-new-line&#34;&gt;Ctrl + Enter (Move to a new line)&lt;/h4&gt;
&lt;p&gt;Moves to a new line below the current line.  Ctrl + Shift + Enter moves to a new line above the current line&lt;/p&gt;
&lt;h4 id=&#34;delete-shortcuts&#34;&gt;Delete shortcuts&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Ctrl + del&lt;/strong&gt; - Delete word forward (removes the rest of the word from cursor)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ctrl + backspace&lt;/strong&gt; - Delete word backward&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ctrl + Shift + K&lt;/strong&gt; - Delete Line&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ctrl + K, Ctrl + K&lt;/strong&gt; - Delete Line forward&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ctrl + K, Ctrl + backspace&lt;/strong&gt; - Delete line backwards&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;mark-commands&#34;&gt;Mark Commands&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Ctrl + k then Ctrl + space&lt;/strong&gt; - Add a mark&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ctrl + k then Ctrl + A&lt;/strong&gt; - Select to mark&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ctrl + k then Ctrl + W&lt;/strong&gt; - Delete To mark&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ctrl + k then Ctrl + X&lt;/strong&gt; - Switch Location with mark&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ctrl + k then Ctrl + G&lt;/strong&gt; - Clear Mark&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;some-quickies&#34;&gt;Some Quickies&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Ctrl + ]&lt;/strong&gt; - Indent a line&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ctrl + [&lt;/strong&gt; - Unindent a line&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ctrl + shift + up/down&lt;/strong&gt; - Swap a line upwards/downwards&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ctrl + J&lt;/strong&gt; - join line with next line&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ctrl + Shift + D&lt;/strong&gt; - Duplicate line&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ctrl + T&lt;/strong&gt; - Transposes the letter/word prior to the cursor with the one after.  I&amp;rsquo;ve never actually found a use for this in my js coding.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;finding-the-power&#34;&gt;Finding The Power&lt;/h3&gt;
&lt;p&gt;Of course the real power of these shortcuts happens when you start using them for real things and combining them together.
Here are a few real life examples of ways sublime text can speed up everyday javascript coding.&lt;/p&gt;
&lt;h4 id=&#34;creating-a-javascript-array-from-a-csv&#34;&gt;Creating a Javascript array from a CSV&lt;/h4&gt;
&lt;p&gt;If you have a CSV full of data that you want to convert into a 2d js array, you can simply select the whole area,
use Ctrl + Shift + L, hit end to move to the end of the lines, insert a &amp;ldquo;],&amp;rdquo; then hit home and add &amp;ldquo;[&amp;rdquo; to the start of each line.
Finally hit escape, then [ to surround the selection with brackets.  Finally hit the right arrow to move to the end of the selection
and move back to delete the trailing comma.  The whole transformation can be done with 10 keystrokes.&lt;/p&gt;
&lt;h4 id=&#34;renaming-a-variable-or-function&#34;&gt;Renaming a variable or function&lt;/h4&gt;
&lt;p&gt;This is an obvious one, but Ctrl + D allows you to easily select every instance of a selection.  You can switch over &amp;ldquo;false positives&amp;rdquo; with Ctrl+K, Ctrl+D&lt;/p&gt;
&lt;h4 id=&#34;code-formatting&#34;&gt;Code Formatting&lt;/h4&gt;
&lt;p&gt;Want to move your curly brackets to a new line after the expression?  Ctrl +D all &amp;ldquo;){&amp;rdquo; instances then move left and enter.  You can move it back by selecting the plain { and using backspace, though you may need to skip some.  Fixing indentation is easy with Ctrl + [ and ctrl + ].&lt;/p&gt;
&lt;h4 id=&#34;editing-in-2-functions&#34;&gt;Editing in 2 functions&lt;/h4&gt;
&lt;p&gt;If you&amp;rsquo;re working on 2 functions, bookmarks can be great ways to easily navigate back and forth between 2 (or more sections of code)&lt;/p&gt;
&lt;h3 id=&#34;this-is-just-the-start&#34;&gt;This is just the start&lt;/h3&gt;
&lt;p&gt;Sublime Text is what you make of it.  If you use it regularly I suggest that you learn to use it well.
You don&amp;rsquo;t need to learn all the shortcuts, but find a few that work for you and make you a faster, more efficient coder.&lt;/p&gt;
&lt;p&gt;If you have suggestions for other great uses of keyboard shortcuts in Sublime Text, please leave them in the comments.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>I hate computing ecosystems</title>
      <link>https://benmccormick.org/2012/12/29/180600.html</link>
      <pubDate>Sat, 29 Dec 2012 19:06:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2012/12/29/180600.html</guid>
      <description>&lt;p&gt;&lt;a href=&#34;http://superuser.com/questions/525673/is-there-a-way-to-edit-text-documents-on-the-iphone-and-sync-them-with-skydrive/525700#525700&#34;&gt;Is there a way to edit text documents on the iPhone and sync them with Skydrive?&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Looks like I need to find a way to get dropbox working on my work laptop again.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Cleaning My Digital House</title>
      <link>https://benmccormick.org/2012/12/28/200000.html</link>
      <pubDate>Fri, 28 Dec 2012 21:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2012/12/29/200000.html</guid>
      <description>&lt;p&gt;I&amp;rsquo;m cleaning my digital house this new year.  I&amp;rsquo;ve been a confessed addict to trying new services and hardware for some time now.  While I don&amp;rsquo;t think there&amp;rsquo;s anything wrong with trying new things and figuring out what you like best, I was beginning to suspect that my experimentation was causing me to be less efficient than I expected.  After reading Chris Webb&amp;rsquo;s &lt;a href=&#34;http://blog.mediumequalsmessage.com/goodbye-ubiquitous-digital-service?utm_source=feedburner&amp;amp;utm_medium=feed&amp;amp;utm_campaign=Feed%3A+mediumequalsmessage%2Fcwebbdesign+%28cwebbdesign%29&#34;&gt;excellent post&lt;/a&gt; on rethinking his digital services and rereading Alex Payne&amp;rsquo;s &lt;a href=&#34;http://al3x.net/2008/09/08/al3xs-rules-for-computing-happiness.html&#34;&gt;Rules for Computing Happiness&lt;/a&gt;, I decided to take inventory of my computing services.  The results were&amp;hellip; illuminating.&lt;/p&gt;
&lt;h3 id=&#34;bad-habits&#34;&gt;Bad Habits&lt;/h3&gt;
&lt;p&gt;Over the past year and a half I have used the following software extensively (used as a main solution for some use case for at least a month):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;5 Desktop Operating Systems (Windows 7, Windows 8, OSX, RHEL, Ubuntu)&lt;/li&gt;
&lt;li&gt;2 Mobile OS&amp;rsquo;s (Windows Phone 7, iOS)&lt;/li&gt;
&lt;li&gt;3 Browsers (Chrome, Firefox, IE9/10)&lt;/li&gt;
&lt;li&gt;3 Desktop Music Clients (iTunes, Zune, Spotify)&lt;/li&gt;
&lt;li&gt;5 Code Editors (Eclipse, Notepad++, Sublime Text 2, Visual Studio, VIM)&lt;/li&gt;
&lt;li&gt;6 Desktop/web Email Clients (Gmail.com, Outlook.com, Outlook, Thunderbird, Mail.app, Sparrow)&lt;/li&gt;
&lt;li&gt;6 Task Management Apps: Things, Omnifocus, Wunderlist, Remember the Milk, Clear, Nirvana (And I downloaded a bunch more)&lt;/li&gt;
&lt;li&gt;3 Note taking solutions (Evernote, OneNote, text notes in markdown)&lt;/li&gt;
&lt;li&gt;4 Blogging Platforms (Blogger,Wordpress, Tumblr, Self-build Django Blog)&lt;/li&gt;
&lt;li&gt;Saving Content For Later (Instapaper, Email, Chrome bookmarks)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;hellip; I could keep going.&lt;/p&gt;
&lt;p&gt;I decided last week that I wanted to simplify the services that I used for the different use cases I&amp;rsquo;d identified during my inventory.  I then wanted to simplify those services according to the following rules.&lt;/p&gt;
&lt;h3 id=&#34;bens-software-rules&#34;&gt;Ben&amp;rsquo;s Software Rules&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Use as little software as possible (this is Alex&amp;rsquo;s first rule, and I think its his best)&lt;/li&gt;
&lt;li&gt;Learn the software I do use (using 100 different things has not let me go deep into any of the software that I use)&lt;/li&gt;
&lt;li&gt;Pay to own and control my content&lt;/li&gt;
&lt;li&gt;Use software that works together across platforms well&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;a-new-leaf&#34;&gt;A new leaf&lt;/h3&gt;
&lt;p&gt;After looking backwards, I took a look at the things I&amp;rsquo;m doing with my software and asked: &amp;ldquo;Do I control my content?&amp;rdquo;, and &amp;ldquo;Is there a way this could be simpler?&amp;rdquo;.  I put the result of my software inventory &lt;a href=&#34;https://gist.github.com/ben336/6b80e52a12204e5b449b&#34;&gt;here&lt;/a&gt;.  In the end I settled on a small(er) subset of the software and services I&amp;rsquo;d used before, and committed to using that subset for 2013. Rather than sampling every single new thing, I&amp;rsquo;m going to work on getting the most out of some of the great software and services that are already available to me, and use my apps as tools rather than toys.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Medium: The end of History and the last website</title>
      <link>https://benmccormick.org/2012/12/25/160000.html</link>
      <pubDate>Tue, 25 Dec 2012 17:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2012/12/25/160000.html</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;the whole experience I’ve just described is part of the argument for a site like Medium. That argument goes: No writer should be in the business of making a personal website. They’re hard to find, readers rarely return to them, and besides—let me just contribute this last part myself—they aren’t even fun to make anymore.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&#34;https://medium.com/the-sea-of-fog/3877ef6d968c&#34;&gt;Robin Sloan, Medium&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;So are websites heading the way of cars?  Becoming so specialized and complicated that only teams of  professionals with specialized knowledge can handle them?&lt;/p&gt;
&lt;p&gt;I would argue that they&amp;rsquo;re differentiated by the virtual nature of their materials.  Websites have effectively no upfront cost after the initial cost of a working computer and internet connection, which is getting lower all the time.  And their virtual nature allows for easy sharing of materials.  This is best seen in the open source movement.  To make a website it&amp;rsquo;s not necessary to write a webserver, because Apache exists.  To create a blog, its not necessary to know php or even html.  You can use Wordpress, Moveable Type or Octopress.  To have a professional design, you can use any of many themes provided by designers across the web for free or cost.&lt;/p&gt;
&lt;p&gt;To build a website, you don&amp;rsquo;t need to know everything, you can build on the foundations laid by others.  I&amp;rsquo;m building this blog on top of octopress, and for now am only contributing content of my own.  But its likely that in the future I&amp;rsquo;ll choose to add more, either with the theming or in plugins.  I won&amp;rsquo;t have to build everything from scratch, but I&amp;rsquo;ll be able to tinker.  It&amp;rsquo;s a middle ground that doesn&amp;rsquo;t exist for cars.  And it means that the amateur web can continue to move along and reap benefits from the work of professional teams, while history continues as normal.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Awesome Software: Trello</title>
      <link>https://benmccormick.org/2012/12/20/070000.html</link>
      <pubDate>Thu, 20 Dec 2012 08:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2012/12/20/070000.html</guid>
      <description>&lt;p&gt;I’ve been using Trello to manage the development process for my new project.  It is an absolutely fantastic tool for managing any type of small scale project.  It keeps things simple and helps you see the big picture. Its deeply flexible workflow consists of a hierarchy of boards, lists, cards and notes/checklists.  You can have multiple team members  sharing a board, with different cards assigned to different members.&lt;/p&gt;
&lt;p&gt;My personal setup has been to use a board to hold a new project, with lists for backlog (To Do), doing, and complete.  The cards hold feature level tasks, and I fill in the details for those tasks into the details section.  I’ve had no need for the card checklists yet, but those could be useful for more complicated features that don’t easily break down into subfeatures I suppose.  This has been great for staying organized.&lt;/p&gt;
&lt;p&gt;Trello is fast and intuitive, with surprising depth for a simple looking concept. It has apps for iOS, android and windows 8, as well as its web app.  I highly recommend it for anyone who has to organize any type of project involving 10 or fewer people.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Bayesian Witch Hunt</title>
      <link>https://benmccormick.org/2012/11/09/070000.html</link>
      <pubDate>Fri, 09 Nov 2012 08:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2012/11/09/070000.html</guid>
      <description>&lt;p&gt;&lt;a href=&#34;http://benhamner.com/2012/11/9/is-nate-silver-really-a-witch/&#34;&gt;Ben Hamner: Is Nate Silver Really a witch?&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Funny nerd tribute from Ben&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Shutdown Tiles for Windows 8 Start Screen</title>
      <link>https://benmccormick.org/2012/11/08/070000.html</link>
      <pubDate>Thu, 08 Nov 2012 08:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2012/11/08/070000.html</guid>
      <description>&lt;p&gt;Solves one of the bigger annoyances I&amp;rsquo;ve had with the OS so far.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://gallery.technet.microsoft.com/scriptcenter/Create-a-ShutdownRestartLog-37c8111d&#34;&gt;Technet Script Center: Create a Shutdown/Restart/Log Off Tile&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Sync Multiple Google Calendars in Windows 8</title>
      <link>https://benmccormick.org/2012/11/07/070000.html</link>
      <pubDate>Wed, 07 Nov 2012 08:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2012/11/07/070000.html</guid>
      <description>&lt;p&gt;Syncing with multiple Google calendars, or any Google calendars that you don&amp;rsquo;t directly control seems like an unsupported feature in Windows 8 calendar app. Since I like to be able to see my wife&amp;rsquo;s calendar as well as my own, and also occasionally create separate calendars for different things, this was a very frustrating limitation. After a bit of research, I found that it was possible. In the end, the workaround is a testament to how much Google has changed over the years.&lt;/p&gt;
&lt;p&gt;###How to do it&lt;/p&gt;
&lt;p&gt;After a bit of frustration trying to make it work through Google directly, I found this workaround on Microsoft&amp;rsquo;s help page:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1. Download &amp;quot;User Agent Switcher&amp;quot; from the Chrome Webstore
2. Say your device is an Iphone 4
3. Go to http://m.google.com/sync
4. Deactivate Javascript in Settings
5. Click your Windows mail device
6. In the URL is this string: &amp;quot;supportMultipleCalendars=false&amp;quot;. Change it to true.
7. Reload the Page.
8. If you have deactivated javascript you can add the calendars.
9. Save
10. Re-add your Google Account to your Windows Calendar app. It now works.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is of course easier if you actually own an iOS device of some kind, since you can skip steps one and 2, and don&amp;rsquo;t have to worry about switching your User Agent String back later. Disabling javascript is accessible under the Safari hub in the iOS settings app. Also I found step 10 to be unecessary. After closing the app and reopening it I was able to see my additional calendars.&lt;/p&gt;
&lt;p&gt;###Why its ridiculous&lt;/p&gt;
&lt;p&gt;For an advocate of the open web, Google sure does manage to make its services hard to use on competing platforms doesn&amp;rsquo;t it? I understood when Google&amp;rsquo;s stuff was crippled on Windows Phone, where it has no native apps, and the web-apps are the feature phone versions. It is a niche market and Google wasn&amp;rsquo;t going to put extra time and energy into optimizing it in order to help a competitor. But Windows 8 is hardly going to be a niche market. Google is actively preventing something that clearly is technically trivial. Doing this in order to discourage users from using your service on a competing platform may be good business, but it is not &amp;ldquo;open web friendly.&amp;rdquo; Its Google&amp;rsquo;s choice to make obviously, and I wouldn&amp;rsquo;t call it unethical exactly, but they&amp;rsquo;ve come a long way from the moral high ground they claimed to occupy in the web space just a few years ago.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>It took a month to get sick of php</title>
      <link>https://benmccormick.org/2012/10/06/060000.html</link>
      <pubDate>Sat, 06 Oct 2012 07:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2012/10/06/060000.html</guid>
      <description>&lt;p&gt;I&amp;rsquo;m not going to claim that its impossible to write nice, well structured code with php. I&amp;rsquo;m not even going to claim that its impossible to write nice, well structured php code with Wordpress. What I did find during my month of running my blog on Wordpress, is that it is much easier to write bad code with Wordpress than it is to write good code. Which is why I ported my blog to a custom self-written blog based on Django.&lt;/p&gt;
&lt;p&gt;I wouldn&amp;rsquo;t recommend that most people (even technically inclined people) do this, because generally the primary purpose of a blog is to produce content. And Wordpress is fantastic for that. Many many people have spent a large amount of time making sure it is very easy to create pretty much any type of content you want to produce on Wordpress without writing a single line of code. However, for somebody like me who wants to tinker and customize (having a place to experiment is part of the fun of this site for me), being forced to deal with the php/Wordpress crapshoot every time I wanted to try writing something was tough to get around.&lt;/p&gt;
&lt;p&gt;Django was an attractive option because it was really easy to get a basic prototype running, and it provides significant flexibility to expand. I got the full functionality of my original Wordpress site back up in 3 days after I first downloaded Django (not 3 full days, 3 busy calendar days). In the process I significantly cut down on my code bloat and increased load time. It was crazy easy to define a basic blog design and have it reflected in the code and database.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;# Basic Blog Format&lt;/span&gt;
&lt;span style=&#34;color:#ff79c6&#34;&gt;from&lt;/span&gt; django.db &lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; models
&lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;Category&lt;/span&gt;(models&lt;span style=&#34;color:#ff79c6&#34;&gt;.&lt;/span&gt;Model):
name &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; models&lt;span style=&#34;color:#ff79c6&#34;&gt;.&lt;/span&gt;CharField(max_length&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#bd93f9&#34;&gt;100&lt;/span&gt;)
&lt;span style=&#34;color:#ff79c6&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;__unicode__&lt;/span&gt;(self):
&lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; self&lt;span style=&#34;color:#ff79c6&#34;&gt;.&lt;/span&gt;name
&lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;Post&lt;/span&gt;(models&lt;span style=&#34;color:#ff79c6&#34;&gt;.&lt;/span&gt;Model):
title &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; models&lt;span style=&#34;color:#ff79c6&#34;&gt;.&lt;/span&gt;CharField(max_length&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#bd93f9&#34;&gt;200&lt;/span&gt;)
content &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; models&lt;span style=&#34;color:#ff79c6&#34;&gt;.&lt;/span&gt;TextField()
pub_date &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; models&lt;span style=&#34;color:#ff79c6&#34;&gt;.&lt;/span&gt;DateTimeField(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;date published&amp;#39;&lt;/span&gt;)
slug &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; models&lt;span style=&#34;color:#ff79c6&#34;&gt;.&lt;/span&gt;SlugField(unique&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;True&lt;/span&gt;)
category &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; models&lt;span style=&#34;color:#ff79c6&#34;&gt;.&lt;/span&gt;ForeignKey(Category)
tags &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; models&lt;span style=&#34;color:#ff79c6&#34;&gt;.&lt;/span&gt;ManyToManyField(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#39;Tag&amp;#39;&lt;/span&gt;, blank&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;True&lt;/span&gt;)
&lt;span style=&#34;color:#ff79c6&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;__unicode__&lt;/span&gt;(self):
&lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; self&lt;span style=&#34;color:#ff79c6&#34;&gt;.&lt;/span&gt;title
&lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;Tag&lt;/span&gt;(models&lt;span style=&#34;color:#ff79c6&#34;&gt;.&lt;/span&gt;Model):
name &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; models&lt;span style=&#34;color:#ff79c6&#34;&gt;.&lt;/span&gt;CharField(max_length&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#bd93f9&#34;&gt;30&lt;/span&gt;)
posts &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; models&lt;span style=&#34;color:#ff79c6&#34;&gt;.&lt;/span&gt;ManyToManyField(Post, through&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;Post&lt;span style=&#34;color:#ff79c6&#34;&gt;.&lt;/span&gt;tags&lt;span style=&#34;color:#ff79c6&#34;&gt;.&lt;/span&gt;through, blank&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;True&lt;/span&gt;)
&lt;span style=&#34;color:#ff79c6&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;__unicode__&lt;/span&gt;(self):
&lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; self&lt;span style=&#34;color:#ff79c6&#34;&gt;.&lt;/span&gt;name
&lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;RelatedLink&lt;/span&gt;(models&lt;span style=&#34;color:#ff79c6&#34;&gt;.&lt;/span&gt;Model):
post &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; models&lt;span style=&#34;color:#ff79c6&#34;&gt;.&lt;/span&gt;ForeignKey(Post)
name &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; models&lt;span style=&#34;color:#ff79c6&#34;&gt;.&lt;/span&gt;CharField(max_length&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#bd93f9&#34;&gt;100&lt;/span&gt;)
url &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; models&lt;span style=&#34;color:#ff79c6&#34;&gt;.&lt;/span&gt;URLField(max_length&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#bd93f9&#34;&gt;200&lt;/span&gt;)
internal &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; models&lt;span style=&#34;color:#ff79c6&#34;&gt;.&lt;/span&gt;BooleanField()
&lt;span style=&#34;color:#ff79c6&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;__unicode__&lt;/span&gt;(self):
&lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; self&lt;span style=&#34;color:#ff79c6&#34;&gt;.&lt;/span&gt;name
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I love Python&amp;rsquo;s clean syntax, and especially the cleanliness of Django&amp;rsquo;s template systems. It is 100x more legible and &amp;ldquo;HTML&amp;rdquo; like than php code (or the jsp code I have to deal with at work). I&amp;rsquo;ve thoroughly enjoyed the experience and am looking forward to working more with Django in the future.
[I wrote 20 short programs in Python yesterday. It was wonderful. Perl, I&amp;rsquo;m leaving you.]&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://benmccormick.micro.blog/uploads/2022/6defb4d912.jpg&#34; alt=&#34;I wrote 20 short programs in Python yesterday.  It was wonderful.  Perl, I&amp;rsquo;m leaving you.&#34;&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>The iPhone 5 Conversation so Far</title>
      <link>https://benmccormick.org/2012/09/19/060000.html</link>
      <pubDate>Wed, 19 Sep 2012 07:00:00 -0400</pubDate>
      
      <guid>http://benmccormick.micro.blog/2012/09/19/060000.html</guid>
      <description>&lt;p&gt;&lt;a href=&#34;http://www.bbc.com/news/technology-19557497&#34;&gt;Blog A&lt;/a&gt;: The iPhone 5 is boring.&lt;/p&gt;
&lt;p&gt;~Blog B~: Customers are buying the iPhone 5; Blog A is an idiot.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://fireballed.org/linked/2012/09/18/jetpack-design/&#34;&gt;Blog C&lt;/a&gt;: Smart Companies make boring products.&lt;/p&gt;
&lt;p&gt;The 3 reactions after every major Apple news: Apple is overrated, Apple is above reproach, This is what Apple just did, so all companies should do that.  Wash, rinse, repeat.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Update June 2014: Apologies for the broken links.  The world does not always respect the permalink.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Update #2: Found a cached version for blog C&lt;/em&gt;&lt;/p&gt;
</description>
    </item>
    
  </channel>
</rss>