<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>Amjad Masad</title>
        <link>https://amasad.me</link>
        <description>Essays</description>
        <lastBuildDate>Wed, 08 Apr 2026 23:29:08 GMT</lastBuildDate>
        <docs>http://blogs.law.harvard.edu/tech/rss</docs>
        <generator>amasad.me</generator>
        <image>
            <title>Amjad Masad</title>
            <url>https://www.gravatar.com/avatar/03637ef1a5121222c8db0ed48c34e124.png?s=200</url>
            <link>https://amasad.me</link>
        </image>
        <copyright>All rights reserved 2019, Amjad Masad</copyright>
        <category>Tech</category>
        <item>
            <title><![CDATA[How to Keep Winning]]></title>
            <pubDate>Fri, 24 Oct 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[ I've always been fiercely competitive. I enjoy everything about it—from training to get better, to building and developing teams, to the stress, pressure, and intensity. And while I love winning, the...]]></description>
            <content:encoded><![CDATA[<p>I&#39;ve always been fiercely competitive. I enjoy everything about it—from training to get better, to building and developing teams, to the stress, pressure, and intensity. And while I love winning, there are very few things I dread more than losing. It just feels awful. This meant that I had to get good at constantly <strong>not</strong> losing. Here are six tactics and principles I learned along the way to protect against failure and keep winning.</p>
<h2 id="1-don-t-die">1. Don&#39;t Die</h2>
<p>Almost everything else you can come back from except death. I&#39;m using &quot;death&quot; both literally and figuratively to mean the point of no return. First, know the death boundaries, and obsess over the extreme downside scenarios and prioritize survival. Visualize all the ways you could die—all the time. In that way I&#39;m very careful, almost paranoid. I ran Replit for eight years with little commercial success, but at no point did we ever get to the red zone when it came to runway—we always had plenty of cash on hand. You&#39;d be surprised by the number of brilliant founders that reach out to me for advice when they&#39;re three months from death.</p>
<p>Once you&#39;re deeply familiar with the death conditions, you can take extreme risks because you know you&#39;ll always come back when things go sideways. Especially in America, and especially in Silicon Valley, people are forgiving of failure. You can come back from almost anything. </p>
<p>At Replit, there were many times when the business sort of worked and any rational founder would have decided to scale it. For example, we had a decently growing business in education and recruiting, but both markets felt unexciting to me—we couldn&#39;t build a big company or achieve our mission that way. So we pivoted. The most recent pivot was from being primarily a coding editor to becoming a natural-language creation interface (vibe coding). Some employees and customers were upset and left (some have since returned), but I knew I had to align with the biggest revolution the world has seen since the internet. When you eventually make it, people won&#39;t just forgive you, they&#39;ll join you.</p>
<h2 id="2-never-quit">2. Never Quit</h2>
<p>Everything takes time. Some startups explode from day one and some prodigies play piano at three, but those are rare—and often fleeting. Most sharp rises end in sharper declines. If you&#39;ve set your mind to something, then why ever quit? If you&#39;re not dead, then you&#39;re still in the game.</p>
<p>When you talk to entrepreneurs who quit on their dreams, even when they still get massively rich through investing, they always have a look of immense pain in their faces when they tell you that they timed it wrong. That they were too early.</p>
<p>Well, you&#39;re only &quot;too early&quot; if you actually quit (or died). They had all the right ideas but stopped short of striking gold. Often, gold is only two strikes away. Don&#39;t let that be you.</p>
<p>When you consider quitting, try to find a different scoreboard. Score yourself on something else: on how many times you dust yourself off and get up, or how much incremental progress you make. Almost always, in your business or life, there are things you can make daily progress on that can make you feel like you&#39;re still winning. Start compounding.</p>
<p>Some of the best businesses started off slow and just compounded all the way to heaven. One of my favorite charts is Amazon&#39;s growth because it&#39;s consistent over many years—and it&#39;s still compounding. It&#39;s really hard to stop companies like this. It&#39;s impossible to stop founders like this. So maybe you&#39;re not winning on some external scoreboard, but you always have your internal scoreboard to measure yourself and your team on. Have patience.</p>
<h2 id="3-lock-in">3. Lock In</h2>
<p>I remember doing a spelling bee when I was maybe in third grade, standing in line waiting to get called on to spell the next word. I looked around me and all the other kids were talking and joking around. I thought that was strange. How could you ever win if you&#39;re not in the mindset of winning. If you&#39;re not locked in? </p>
<p>For me, I would stand there and keep reciting difficult words. And although I was slightly dyslexic, I still won every freaking spelling bee. With this simple trick, I dominated it so much to the point that my teachers, who loathed me for being a slacker, once tried to rig it in favor of their obedient A-students (I still won).</p>
<p>On a day I have to perform, I&#39;m impossible to be around. I&#39;m in the winning mindset. If I can observe how others are doing, I will study their every move. I recently participated and won a timed car race. While waiting, I watched everyone&#39;s mistakes and learned from them. By the time I went to do my trial, I knew exactly the bare minimum I needed to do to put myself in a winning position. After you eliminate risk, it&#39;s all upside from there.</p>
<h2 id="4-do-hard-things">4. Do Hard Things</h2>
<p>Most people do the obvious thing. They don&#39;t want to look weird or different—but winning is weird and different. You&#39;re definitionally different because you stand apart from everyone else as the ultimate winner. </p>
<p>I used to be a pro gamer, and when my friends and I picked up a new video game, everyone would follow the game&#39;s instructions and do the obvious thing. On the other hand, I would explore the edges of the game. I&#39;d explore every weird build, every different weapon, and frankly look like a noob for a long time. That&#39;s good. They&#39;ll underestimate you. But you&#39;re compounding. And eventually, you&#39;ll go vertical, creating a massive distance between you and the next participant before they know what hit them.</p>
<p>People by nature take the path of least resistance. If it&#39;s working, they&#39;ll keep going. Doing hard things means you&#39;re going on an untraveled path. It&#39;s risky.</p>
<p>When I started working on Replit many years ago, venture capitalists would look at our competitors and see that they were growing faster or making superficially more progress, and they&#39;d ask us &quot;why not just do this or that?&quot; But it was never that simple. I wanted to build real technological depth. Something lasting. If it&#39;s easy, then there is no real lasting advantage. It&#39;s easy to create the surface thing, but the right (hard) infrastructure technology compounds.</p>
<p>In building a technology company, you&#39;re often faced with a strategic decision of whether to build or buy. Every build-or-buy decision should be treated with care, but what&#39;s certain is that buying tech is strategically fraught because once you run into the limits of the technology, you can&#39;t fundamentally change it. But when you build, you&#39;ll be able to adapt a lot faster and find ways to win on the tail events—e.g. valuable yet rare use-cases—that are impossible to handle with an outsourced platform.</p>
<p>For example, at Replit we built a distributed file system to solve the problem of collaborative coding. The easy solution was to buy any one of those services that give you an API to do collaborative editing. Instead, we took the problem one level deeper and built a powerful abstraction. A filesystem where any operation can be reversed, where it can be forked in a fraction of a second, and can be easily stored and backed up. When coding AI agents became possible, we quickly adapted the technology, and now we use this tech to do parallel agents—and as a side effect of concurrency features we were able to build a time-travel feature that&#39;s important for reversing destructive agent actions.</p>
<h2 id="5-play-by-the-rules">5. Play by the Rules</h2>
<p>You might think that maximizing risk means you can break the law or do unethical or immoral things. But in my opinion, there&#39;s something about the universe that really doesn&#39;t reward that. Yes, there are exceptions—there are slimebags that make it really big, and evil companies that maintain a winning position—but those are either the exceptions or their time will come. For the most part, if your competitors are lying, deceiving, or taking unethical shortcuts, it&#39;ll only help them in the short term. Don&#39;t be tempted to do the same. Stay focused.</p>
<p>Playing by the rules is hard. It&#39;s doing the hard thing, and that has the side effect of forcing you to innovate your way out of problems. Those innovations might  compound in interesting and weird ways resulting in longterm moats. Think of Apple and how taking privacy and security seriously—despite competing against Microsoft, which didn&#39;t care about either at the time—created a lasting consumer trust advantage.</p>
<h2 id="6-put-something-back">6. Put Something Back</h2>
<p>Steve Jobs talked about &quot;putting something back in the pool of human experience.&quot; He said that putting something back was &quot;extremely neat&quot;—I agree! </p>
<p>But it&#39;s not just neat. It&#39;s not just an ethical good, it might also benefit you in the future. Karma seems real. When you put something back into that pool, your reputation will grow, people will be familiar with your work, and they will want to be around you and work for you. Winning can compound by giving back. Win and give to win more later.</p>
<p>I always liked open-sourcing software, sharing my experience, and talking publicly about how I&#39;m building things—in some cases an entire roadmap. For example, Replit Agent was the first fully generative software creator on the market that&#39;s accessible to anyone. I shared the roadmap for that in its entirety in a TED talk almost a full year before launch. Our roadmap was public—it still is—but I can&#39;t remember a time where that was a disadvantage. Ideas are important, but what&#39;s precious is the generating function. The well  from which those ideas spring.</p>
]]></content:encoded>
            <author>amjad.masad@gmail.com (Amjad Masad)</author>
        </item>
        <item>
            <title><![CDATA[Civilizational Primitives]]></title>
            <pubDate>Wed, 16 Nov 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[ At the dawn of civilization, with the introduction of the agricultural revolution, humans needed to coordinate in larger numbers so _the hierarchy_ emerged as the primary organizing tool. People orga...]]></description>
            <content:encoded><![CDATA[<p>At the dawn of civilization, with the introduction of the agricultural revolution, humans needed to coordinate in larger numbers so <em>the hierarchy</em> emerged as the primary organizing tool. People organized into pyramid-like structures with ranks and different entitlements and responsibilities. This structure proved useful and spread to apply to every aspect of civilization: we had kings and peasants, owners and serfs, clergy and laymen. </p>
<p>With the industrial revolution, we needed ways to coordinate in larger numbers and a more decentralized manner. The <em>assembly line</em> emerged as the basic civilizational primitive of this era. Every node — be it a person, a company, or a nation — was hyper-specialized and produced one thing with a standard interface to handle transactions between nodes. While the hierarchy never disappeared, many aspects of society were remade in the shape of the assembly line. Children go through school one grade at a time, the economy is made of supply chains and consumer-producer pairs, money is printed by the Fed and filtered to the economy through a chain of financial institutions. Even software is built by layering on components on a stack going through different stages and pipelines. </p>
<p>Today, I believe we are going through another major transition: The Information Revolution. While it’s become out of fashion to point this out, it’s undeniable that civilization is being rebuilt. So what is this era’s civilizational primitive? It seems clear to me it’s <em>the network</em>. Unlike the pyramid and the supply chain, the network topology requires less coordination; it’s emergent, self-improving, and self-organizing. The radio, telephone, and the internet are straightforward examples of networks. But if you look deeply, you’ll see that networks are infecting almost everything else: money flows through payment networks (and Bitcoin is bootstrapping money on the network), startups and open-source proved that flatter network-like structures could be a superior way to work, and even software is changing to be built through networks of packages, APIs, and cloud computing. And while schools remain stubbornly unchanged, innovation at the edges resembles a network: kids learn to code and make on networks like Scratch and <a href="https://replit.com">Replit</a>, and they learn how to solve problems on networks like <a href="https://synthesis.is">Synthesis</a>. How will networks change government and politics? Arguably politics is already changed. Today policy is made not top-down but through a decentralized network of universities, think tanks, donors, and politicians. <a href="https://thenetworkstate.com">The Network State</a> is an attempt to describe the future of governance. </p>
<p>While the network, like its predecessors, is a neutral tool, I believe it creates a slightly more free world. Strict hierarchies meant that people were stuck in castes and bad luck. The assembly line reduced people to cogs in a giant machine. While the network affords people more freedom to self organize and choose which networks to affiliate with.</p>
]]></content:encoded>
            <author>amjad.masad@gmail.com (Amjad Masad)</author>
        </item>
        <item>
            <title><![CDATA[Investing in Synthesis]]></title>
            <pubDate>Thu, 21 Apr 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[ Computers give humanity the power to solve some of the most critical problems our species has ever faced. However, until today, we have failed to leverage this unprecedented tool; we teach kids to be...]]></description>
            <content:encoded><![CDATA[<p>Computers give humanity the power to solve some of the most critical problems our species has ever faced. However, until today, we have failed to leverage this unprecedented tool; we teach kids to be mere consumers of this powerful machine. To change this, society needs three things:</p>
<ul>
<li>Access to the tool</li>
<li>Education in the complex skills necessary to use it</li>
<li>Education in the problem-solving skills necessary to maximize the potential for human progress</li>
</ul>
<p>At Replit, we’re making computer programming accessible and learnable for anyone, no matter their background, location, or socio-economic status. That covers points 1 and 2, but what about point 3? We need a way to offer any kid from anywhere the opportunity to learn collaboration, critical thinking, and problem-solving so they can capitalize on the promise of computers.</p>
<p>For this reason, I’m pleased to announce that I’m leading along with Balaji Srinivasan a new <a href="https://www.synthesis.is/fundraise-amjad-balaji">$12M investment</a> in <a href="https://synthesis.is">Synthesis</a>, the innovative education program where kids learn to solve complex problems by playing team games.</p>
<p>I first met Joshua Dahn, the co-founder of Synthesis, when I visited the Ad Astra school on the campus of SpaceX. I had heard they were using Replit to learn to code and build projects, so I visited expecting a regular school. But what I saw was radical. Elon Musk hired Josh to build a lab school for his kids and SpaceX engineers–and what Josh created blew me away. Now, Synthesis is taking the most popular class from that school and scaling it up for kids from across the globe. They designed Synthesis to train supercollaborators, who can work together to solve complex problems to advance human civilization.</p>
<p>Last month, I was hanging out with Chrisman Frank, the CEO of Synthesis. He shared their progress with me, and I couldn’t believe what they had accomplished. They’re teaching thousands of kids the skills needed to move civilization forward. I spoke with Balaji, and we both agreed that we needed to do whatever we could to help Synthesis succeed.</p>
<p>Balaji notes six features that make Synthesis a particular company in his <a href="https://balajis.com/synthesis">announcement</a>. They bear repeating here:</p>
<blockquote>
<ol>
<li>First digital, then physical. A full replacement for the education system will eventually require physical locations. Too many parents depend on state-run schools for childcare. However, it’s important to go digital first, then physical. Synthesis is building a networked community online and then, later, creating physical infrastructure as needed be.</li>
<li>Scale what can be scaled. Today’s K-12 instruction can be decoupled into (a) curricula, (b) small group tutoring and (c) de facto childcare. While the tutoring and childcare components will continue requiring hands-on attention for each student, the curricula can be created by world class instructors and cost-effectively scaled to millions of children. That means one could have the polish of a Hollywood movie or an AAA-quality game for educational content, which is what Synthesis is working on.</li>
<li>Go direct. Legacy media is incentivized to protect legacy systems. Therefore, companies offering an exit must go direct to customers and build their own distribution. Otherwise, they’ll either get politically attacked or forced to fold back into the values of the incumbent system. And so Synthesis is reaching parents entirely through social media and eschewing legacy media corporations.</li>
<li>Make exit easy. Our education systems won’t reform from within. The necessary improvements require too much change. The only real solution is to create something better from the ground up that’s so attractive users can’t help but exit the old system. Something like that doesn&#39;t arise overnight - it&#39;s proved out in stages, by people gradually opting out of the current system, providing feedback and driving features, till the parallel system is better in all respects and ready for broad adoption. This, too, is part of the Synthesis strategy.</li>
<li>Win and help win. Finally, the aim of education should be to train kids to grow the global pie for humanity so all can benefit. In other words, kids need to learn how to work together and succeed in a competitive environment so that they can contribute to the common good. And Synthesis believes that teaching values like this is as important as teaching calculus.</li>
</ol>
</blockquote>
<p>I believe that Replit + Synthesis could become the educational stack for millions of kids worldwide. In the past, kids had to go through K-12 then university education before contributing to the real world, but things are changing fast for a few reasons:</p>
<p>First, the traditional track isn’t available to many people simply because of where they were born. Second, the few who graduate often end up with loads of debt and little to no hirable skills. Third, and most importantly, it seals them off in school for 14+ years and then expects them to offer something productive to society.</p>
<p>Together, Synthesis and Replit are fixing this problem. Synthesis lets any kid anywhere collaborate with peers to practice solving humanity’s toughest challenges, like managing wildfires and colonizing space. Replit empowers these kids to learn code, turn their ideas into real solutions, and build businesses around them online.</p>
<p>No barriers to entry. No unnecessary debt. No more waiting.</p>
<p>In essence, Synthesis is the complement of Replit. To build the future, the next generation needs two critically essential skills. They need to know how to think with computers and collaborate with humans. Replit lets anyone learn the first. Synthesis allows anyone to learn the second. I can’t think of two higher leverage ways to move society forward.</p>
<p>If you have kids ages 8-14, you can sign them up for Synthesis <a href="https://www.synthesis.is/">here</a>.</p>
<p>If you’d like to join their team, view their <a href="https://www.synthesis.is/careers">open positions here</a>.</p>
]]></content:encoded>
            <author>amjad.masad@gmail.com (Amjad Masad)</author>
            <enclosure url="https://amasad.me/public/images/synthesis.png">
            </enclosure>
        </item>
        <item>
            <title><![CDATA[Why Learn Compilers]]></title>
            <pubDate>Wed, 29 Dec 2021 00:00:00 GMT</pubDate>
            <description><![CDATA[ A sufficient understanding of computers is impossible without learning how compilers and their parts work. It is like stepping into the computer's mind and seeing how it feels from the inside. Compil...]]></description>
            <content:encoded><![CDATA[<p>A sufficient understanding of computers is impossible without learning how compilers and their parts work. It is like stepping into the computer&#39;s mind and seeing how it feels from the inside. Compilers are also some of the most satisfying programs to write. Finally, learning compiler technology can open new artistic avenues for you, and provide a skill bordering on a superpower.</p>
<h2 id="a-most-fun-sandbox">A most fun sandbox</h2>
<p>Because the most basic compiler architecture is standard, you have limited boundaries and degrees of freedom when designing one. This might sound restricting, but actually, it&#39;s freeing because you get to play in a predictable sandbox. </p>
<p>And because compilers are largely deterministic closed-system problems -- for each input, there is one and only output -- it makes it really fun to iterate on a program without having to worry about external dependencies or a complicated setup. This lends itself nicely to test-driven development -- you can unit-test the component parts and write end-to-end tests for the compiler as a whole.</p>
<p>Writing the test &amp; debugging framework around compilers can also be really fun. To test a parser, for example, you need to run assertions on massive syntax trees, and you need to output helpful failure messages. You can go as far as writing a Domain-Specific testing language to make testing more pleasant.</p>
<h2 id="a-most-magical-flow-experience">A most magical flow experience</h2>
<p>The most fun I had coding was when I led the JavaScript infrastructure team at Facebook. We were tasked with replacing <a href="https://github.com/facebookarchive/jstransform">JSTransform</a>, a string-manipulation-based JavaScript transpiler. Honestly, it&#39;s amazing it worked at all, but it didn&#39;t work very well. I resided in NYC but went up to our office in Cambridge to work with one other engineer there. However, I ended up mainly working alone, coming in every day for two weeks and writing code for 10 hours a day. I was in a state of flow.</p>
<p>The leading expert on &quot;flow,&quot; Csikszentmihályi, identified that for a human to enter a this state, they need to be able to get direct and immediate feedback, for the problem to be well-defined, to have a balance between one&#39;s ability level and the challenge, and have a sense of control over the situation. I can&#39;t think of a better programming task that hits all those points than writing a compiler.</p>
<h2 id="useful-skills">Useful skills</h2>
<p>I joined Yahoo! for my first job out of college, who&#39;d just acquired a company in my hometown. As part of the acquisition, we were tasked with moving to the Yahoo! stack, and they were adamant about us using YUI instead of jQuery. The task fell on my lap, which felt like a crushing mountain of repetitive work. </p>
<p>Like any good (read: lazy) programmer, I decided to automate the task. The task was more intricate than simply a massive search and replace because you had to deal with many variations of names, formatting, and patterns. I&#39;d been learning about compilers and ASTs, and I figured this was an excellent time to deploy my newfound skills. </p>
<p>First, I backfilled into YUI some jQuery-like to make the transition easier. Then I wrote a transformer that took in jQuery code and automatically translated the calls into YUI code. </p>
<p>A many-month project turned into a week project. My colleagues were dumbfounded when they saw the volume of patches flying out of my desk. This is the kind of leverage that compiler technology can give you. </p>
<h2 id="do-it-for-the-art">Do it for the art</h2>
<p>What do compilers have to do with art? Surprisingly I&#39;ve found them a great source of inspiration for art projects. </p>
<p>When you look at a program in your editor, you&#39;re often able to deduce what the program does from its shape or <a href="https://www.dreamsongs.com/Files/PatternsOfSoftware.pdf">pattern</a>. Programs have a visual identity; many are beautiful. So if they have a form, wouldn&#39;t it make sense to also have a sound? </p>
<p>So how do you make code audible? One way, I thought, is to make running a program sound like something. It wasn&#39;t clear how I would do that. A more straightforward idea was to give the syntax tree sound. What does a code block sound like? A statement? A conditional? </p>
<p>I decided to map the sounds from an 808 drum machine to AST node types. Take a listen <a href="http://soundofjs.com/">here</a>, and if you listen to enough programs, I believe you&#39;ll be able to identify them in the same way we recognize the shape of a program. You can also toy with the mappings themselves and make them sound differently. </p>
<p><img src="/public/images/soundofjs.png" alt="soundofjs.com screenshot"></p>
<p>Another art project that I had the pleasure to play a <a href="https://github.com/nasser/---/commits?author=amasad">small part</a> in was <a href="https://www.albawaba.com/editorchoice/alb-arabic-computer-programming-language-understands-calligraphy-861614">Qalb</a>, the Arabic programming language. The most fun aspect of the project was not the language or the tooling to which I contributed, but it was the fact that Ramzi, the artist behind the project, showed that you could print programs as Arabic calligraphy tiles.</p>
<p><img src="/public/images/qalb.png" alt="qalb program"></p>
<p>Finally, I can&#39;t talk about compiler art without mentioning <a href="https://amasad.github.io/DOMQL/">DOMQL</a>, a satrical project that add a SQL-like language to the browser and claims it&#39;s a better frontend programming experience than JavaScript.</p>
<h2 id="a-better-coding-ux">A better coding UX</h2>
<p>In my <a href="https://amasad.me/right">Computers Doing The Right Thing essay</a>, I talked about how we can build more delightful software by detecting user intent. I gave the example of deducing the software packages the programmer wanted to install by from the code, and installing them for the user. This is of course, done by parsing import statements in the respective language. The code for this is open-source -- here is, for example, the <a href="https://github.com/replit/upm/blob/715e4d1bd301b66b209a6c5cf1345f59aaa0799a/internal/backends/nodejs/grab.go#L91-L216">Go-based JavaScript parser for that</a>.</p>
<p><img src="https://amasad.me/public/images/import.gif" alt="upm in action"></p>
<p>To build delightful coding experiences, it helps to master parsers.I&#39;m incredibly excited about the work we&#39;re doing with our live game programming environment: Kaboomjs.</p>
<p><blockquote class="twitter-tweet"><p lang="en" dir="ltr">Preview of upcoming creative coding magic (and like everything we do, multiplayer). <a href="https://t.co/7i4KakNpeW">pic.twitter.com/7i4KakNpeW</a></p>&mdash; Amjad Masad ⠕ (@amasad) <a href="https://twitter.com/amasad/status/1474455969685901312?ref_src=twsrc%5Etfw">December 24, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></p>
<h2 id="what-is-it-like-to-be-a-compiler-">What Is It Like to Be a Compiler?</h2>
<p>As a programmer, you spend much of your day conversing with your compiler. If you&#39;re not happy at work, there&#39;s a good chance it&#39;s because you have a bad relationship with your compiler. Maybe it&#39;s too slow, taking you out of the flow state. Perhaps it&#39;s giving you inscrutable errors. Or maybe the language has undefined edge-cases, and you don&#39;t know what kind of code the compiler is emitting. </p>
<p>All those are reasons to get in and understand how compilers work. Once you do, you&#39;ll have a whole new appreciation of programming and how languages are constructed. You&#39;ll be able to reason about your programs in new ways, and you can predict how it could go wrong. </p>
<p>I hope this inspires you to design a toy programming language or compiler. Last year, at Replit, we ran a <a href="https://blog.replit.com/pljamresults">massive programming language jam</a>, and it turned out to be one of the funniest hackathons we ran. It introduced many people to the joy of language design and compiler construction, and I hope to repeat this again in the future. </p>
]]></content:encoded>
            <author>amjad.masad@gmail.com (Amjad Masad)</author>
        </item>
        <item>
            <title><![CDATA[Computers Doing The Right Thing]]></title>
            <pubDate>Fri, 24 Dec 2021 00:00:00 GMT</pubDate>
            <description><![CDATA[I'm fascinated by the idea of computers doing The Right thing without explicit user input. Today this is most apparent in autocorrect, but the idea -- in a more advanced form -- goes back to the early...]]></description>
            <content:encoded><![CDATA[<p>I&#39;m fascinated by the idea of computers doing The Right thing without explicit user input. Today this is most apparent in autocorrect, but the idea -- in a more advanced form -- goes back to the early days of computing. </p>
<p>I think if software designers embraced some of the ideas I&#39;m going to talk about here, computers will be much more delightful to use. We won&#39;t need endless pages of menus and buttons. And humans can be free to think about their task as opposed to the software that&#39;s doing the task. </p>
<h2 id="dwim">DWIM</h2>
<p>Interlisp is one of the most fascinating could-have-been computer systems in history. It shipped with one of the first from-the-ground-up interactive programming environments, structured editor, and many other innovations. Most impressive was the concept of Do What I Mean (DWIM).</p>
<p><img src="/public/images/dwim.png" alt="interlisp manual"></p>
<p>The most basic DWIM feature is one of spell-correction, but it goes way further than that. It can fix some basic logic errors and even lets the programmer define their own DWIM logic. </p>
<h2 id="from-correction-to-intention">From correction to intention</h2>
<p>DWIM and other contemporary examples (like Google&#39;s &quot;did you mean?&quot;) are about correcting user errors. A more advanced and fascinating idea is for the computer to detect intention and act on it. Humans do it all the time; we see the intention in other people and act on it. Like for example making way for someone who&#39;s walking towards you. </p>
<p>Software too can and should do basic intention-detection and I&#39;m surprised I don&#39;t see it much in the wild. Let&#39;s look at examples of how we used it at work. </p>
<h2 id="intent-based-development-environment">Intent-based development environment</h2>
<p>At Replit, we&#39;re really passionate about making a simple yet powerful programming environment. The environment needs to be very intuitive for newbies and should be enjoyable for experts. </p>
<p><img src="/public/images/helloworld.png" alt="hello world"></p>
<p>The environment always starts with 3-columns, something we&#39;ve tested and made sure that newbies intuitively get: files, editor, console. That&#39;s great, but now <strong>what if you want to do web development?</strong></p>
<p>You simply write the code, and the environment will open a new pane to show you the output. </p>
<p><img src="/public/images/web.png" alt="web dev"></p>
<p>So how does it work? We hook into the Linux Audit system and watch for any new open sockets. In other words, if you start a server we&#39;ll assume you want to see the output from it. And in the vast majority of cases, we&#39;re right.</p>
<p>Web development is not the only thing people want to do on Replit, many would also like to build games, plot, or boot up old operating systems for fun. In this case, if you wrote the code, or invoked the program that wants to do graphics, we will detect that and stream VNC down to your browser. So how do we do it? Initially, we relied on <a href="https://jvns.ca/blog/2014/11/27/ld-preload-is-super-fun-and-easy/">LD_PRELOAD</a> which allows you to override arbitrary function calls and inject your own logic. Pretty neat and works for other intent-based functionality. However, we decided to <a href="https://blog.replit.com/native-graphics-love">move away</a> from that, here is the new approach:</p>
<blockquote>
<p>In order to avoid using the LD_PRELOAD trick, we took a page out of systemd&#39;s socket activation feature, so that we detect the intent of a repl wanting to communicate with X by opening the socket to the X server, and launch the server + Window Manager at that point in time.</p>
</blockquote>
<p>Finally, much of software development today involves open-source packages. However, package manager can be a bit of pain to use, and honestly they can take out of the flow of coding. So while we do have native UI for package management, we also built a system to detect your intent to install an OSS package and simply do it for you. </p>
<p><img src="/public/images/import.gif" alt="import"></p>
<h2 id="intent-detection-is-hard-but-worth-it">Intent detection is hard but worth it</h2>
<p>As you can see intent-detection required system-level knowledge and hacking. At Replit, we&#39;re completely obsessed with creating delightful experiences so we go the extra mile to make it happen. But it&#39;s worth recognizing that it&#39;s not perfect. Sometimes we get it wrong, and the user can get into a pretty messed-up state. </p>
<p>While complete detection of intent is an <a href="https://en.wikipedia.org/wiki/AI-complete">AI-complete problem</a>, there are a lot of heuristics that we can apply. Including using modern AI techniques. And software can and should get smarter as more people use it. </p>
<p>I hope this inspires someone to make their software Do The Right Things. </p>
]]></content:encoded>
            <author>amjad.masad@gmail.com (Amjad Masad)</author>
        </item>
        <item>
            <title><![CDATA[Learning to Fight]]></title>
            <pubDate>Mon, 15 Mar 2021 00:00:00 GMT</pubDate>
            <description><![CDATA[ <iframe width="560" height="315" src="https://www.youtube.com/embed/-DDZ1A4Q0KY" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyrosco...]]></description>
            <content:encoded><![CDATA[<iframe width="560" height="315" src="https://www.youtube.com/embed/-DDZ1A4Q0KY" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

<p>Running a growing business is thrilling. Serving customers is incredible, and growing revenue feels great. But there is only so much excitement in running your average — say b2b — startup. </p>
<p>But suppose your company is doing something so radical it changes culture. In that case, you have to be ready to be surprised, delighted, horrified, and viscously attacked. </p>
<p>In prior eras, a b2b startup founder might&#39;ve been a skilled trader. Whereas a successful culture-changing founder would&#39;ve started a revolution or a religion.</p>
<p>When you&#39;re challenging norms, you have to be ready to fight the gatekeepers, the useful idiots, and the final boss — the priesthood — those who maintain the status quo.</p>
<p>It&#39;s essential to cultivate your community. Provide protected spaces to assemble because existing spaces are hostile to change. Build tools for collective action and encourage solidarity. Build allies wherever you can find them — the outsiders, the weirdos, and the radical thinkers are your best friends.</p>
<p>As a leader, build up stress tolerance. Find habits that clear the mind. Learn how to function with little sleep but take sleep seriously. </p>
<p>In quiet times don&#39;t let your guard down. Use those times to train for the next battle. But also celebrate good times and reflect on your victories and losses.</p>
<p>Understand the political milieu. Try not to swim upstream unless it&#39;s essential for your mission. Better to ride or entirely circumvent it. </p>
<p>Tell your story. Don&#39;t rely on the media machine to tell it for you because, ultimately, they&#39;re part of the gatekeeping class. Many are owned by the priesthood.</p>
<p>When building your crew, prefer zealots. It&#39;s too risky to have skeptics in your midst. But prize truth, and allow criticism. Build an organization that is both rooted in and unsatisfied with reality. </p>
<p>Enjoy yourself. And remember that quitting is never an option. When it&#39;s darkest and most intense, you&#39;re closest to victory.</p>
]]></content:encoded>
            <author>amjad.masad@gmail.com (Amjad Masad)</author>
        </item>
        <item>
            <title><![CDATA[The Hyperreal]]></title>
            <pubDate>Sat, 13 Mar 2021 00:00:00 GMT</pubDate>
            <description><![CDATA[ It's normal to get excited by social media likes. Some say social media is "fake." But to the receiver of the like, they feel appreciated and heard, and to them, that's real. It's perhaps more real t...]]></description>
            <content:encoded><![CDATA[<p>It&#39;s normal to get excited by social media likes. Some say social media is &quot;fake.&quot; But to the receiver of the like, they feel appreciated and heard, and to them, that&#39;s real. It&#39;s perhaps more real than going out into the world and saying interesting things and receiving real-world &quot;likes&quot; and praise. The activity is reduced to its essence and delivers intense satisfaction. Likes are hyperreal. </p>
<p>For something to be fake, it can&#39;t produce the intended result. It should be counterfeit. But hyperreal is the opposite. To make a hyperreal object from a real one, take only the details that excite the mind — like getting praise — intensify them, and drop everything else. When you reduce food to its most intense elements — sweet &amp; salt — you get hyperreal (junk) food.  That is the formula for hyperreality. </p>
<p>Hyperreality is exciting, but too much of it is destructive to humans. It takes us out of our natural flow and makes us into addicts. Now you might object with something like &quot;everything in moderation,&quot; which is trite and true. But be prepared to fight the modern technological system optimized to produce hyperreality. </p>
<p>You might blame &quot;capitalism&quot; for working against our better angels. It is, after all, very efficient at producing hyperreality. But you&#39;d be wrong because humans have been making hyperreality since cave drawings.</p>
<p>Communism produces hyperreality too. It is hyperreality. It takes a naturally occurring thing — family and community — and intensifies its most attractive elements. It&#39;s an intoxicating hyperreal vision. </p>
<p>Are we doomed to eternal hyperreality addiction? It is a potential answer to Fermi&#39;s Paradox. Intelligent life evolves until all it does is produce and consume hyperreality at the expense of exploring the stars. </p>
<p>I don&#39;t think we&#39;re doomed though. And I don&#39;t think regulation is the answer either. Religions have dealt with the destructive nature of hyperreality. Why do you think you can&#39;t draw pictures of people or animals in Islam? A restriction that generated an art culture rooted in abstract (unreal) shapes.</p>
<p>The secular West is especially vulnerable to hyperrealism because societal norms that could protect us are considered oppressive. I love the West&#39;s renegade aspect. It resulted in innovative art, science, and technology. But it left us unprotected against hyperreality.</p>
<p>Whatever comes next — may be a techno-futurist religion — needs to address this issue. </p>
]]></content:encoded>
            <author>amjad.masad@gmail.com (Amjad Masad)</author>
        </item>
        <item>
            <title><![CDATA[On Hosting Sites from Your Editor]]></title>
            <pubDate>Mon, 08 Mar 2021 00:00:00 GMT</pubDate>
            <description><![CDATA[ This website is hosted on an [editor](https://replit.com/@amasad/my-blog). I can update it live and I can even see you visiting it in my editor [console](https://blog.replit.com/internet-of-fun).  Th...]]></description>
            <content:encoded><![CDATA[<p>This website is hosted on an <a href="https://replit.com/@amasad/my-blog">editor</a>. I can update it live and I can even see you visiting it in my editor <a href="https://blog.replit.com/internet-of-fun">console</a>.</p>
<p>This idea is not too far from how we used to make websites in the 90s and early 2000s. You wrote your code and FTP&#39;d it into remote server and restart the webserver process to pick up the changes. Today, most people do it by git-pushing to a PaaS provider. I&#39;ve been hosting apps, sites, bots, and microservices from my editor for the last two years, and in this post, I&#39;ll share my experience. While I&#39;ve been doing in Replit, where it collapses your entire workflow into your code -- a code-first environment -- the following applies to anyone who&#39;s hosting code directly from where they wrote it.</p>
<p>When writing code, the development environment feels closest to you. It&#39;s where you are making the changes and seeing your creation come to life. After coding, in a typical workflow, you push up your code for storage and sharing (to something like GitHub). If your changes are ready to release, you&#39;ll also push them to a hosting provider (say Heroku). Here is a diagram of it:</p>
<p><img src="/public/images/hosting.png" alt="a diagram showing three different environments: localhost, production, git"></p>
<p>The moment you send your code to a remote environment, you&#39;ve created distance between you and your creation. It&#39;s living in a different environment where it&#39;s not easy to inspect and update. You&#39;ve fragmented your workflow and now have two other locations where your code lives, and while git is great and maintaining copies of code, you&#39;ve introduced multiple potential sources of truth. </p>
<p>This destroys momentum especially for early-stage startups, side-projects, and those who are learning to code. Sadly, the &quot;industry standard&quot; often gets applied indiscriminately, robbing people of a superior mode of creation and all the fun and reward that comes with it. </p>
<p>The alternative: </p>
<p><img src="/public/images/hosting2.png" alt="a diagram showing one environment"></p>
<p>When hosting from your editor, you&#39;re moving fast, updating the site and seeing crashes and debugging issues in realtime. For example, in Replit, I can enter the production repl and see active connections, inspect, and even hot-update live objects. </p>
<p><blockquote class="twitter-tweet"><p lang="en" dir="ltr">I was wondering if the app is already getting usage and one of the wonderful things about hosting on <a href="https://twitter.com/replit?ref_src=twsrc%5Etfw">@Replit</a> is getting a live repl on the hosted app. <br><br>Here I just got a reference to the db and listed the entries. <a href="https://t.co/UIoERFc50D">pic.twitter.com/UIoERFc50D</a></p>&mdash; Amjad Masad ⠕ (@amasad) <a href="https://twitter.com/amasad/status/1332029622075047936?ref_src=twsrc%5Etfw">November 26, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></p>
<p>Having a production repl is super valuable. Paul Graham recounts how he used the Hacker News prod repl to react to an issue from his phone: </p>
<p><blockquote class="twitter-tweet"><p lang="en" dir="ltr">I once had to write code on a phone, after HN mistook investor usage on Demo Day for a DDoS attempt and started ignoring the venue&#39;s IP address. I had to log into HN on a phone and paste a fix into the repl. This looks a lot more civilized.</p>&mdash; Paul Graham (@paulg) <a href="https://twitter.com/paulg/status/1255235112226238466?ref_src=twsrc%5Etfw">April 28, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></p>
<p>Another issue I&#39;ve run into with today&#39;s standard workflow is projects going stale. After leaving a project for a few months the barrier to going back to hacking feels high: I&#39;d have to pull, set up the dev environment again, and figure out how the hosting provider is configured. However, when hosting from my editor, I open up the project, and I&#39;m right there hacking and &quot;deploying.&quot;</p>
<p>Because the distance from creation is reduced, I also start (and complete) many more projects. I&#39;m quick to spin up something or to automate a piece of work. At work, because Replit feels close and fast, we spin up many bots to automate tedious tasks or introduce fun and serendipity. </p>
<p><img src="https://pbs.twimg.com/media/EuCd-dvVkAwNO8K?format=jpg&amp;name=medium" alt="lunch bot"></p>
<p>Finally, in cases of emergency, it also helps to be able to code live. We&#39;ve been able to respond to emergencies  at breakneck speed. For example, a few months ago PyPi quitely deprecated their package search API which we use in our packager UI. Luckily, we found a package that searches PyPi via scraping the site. We spun up an alternative on Replit in 30 minutes:</p>
<p><blockquote class="twitter-tweet"><p lang="en" dir="ltr">Multiplayer <a href="https://twitter.com/replit?ref_src=twsrc%5Etfw">@replit</a> story: <br><br>3rd party service deprecated w/ no warning 😱<br><br>I spun up a repl with and prototyped replacement ⚡️<br><br>Single-threaded couldn&#39;t handle 1 rps 😢<br><br>Someone jumps in w/ <code>uwsgi</code> now we&#39;re at 3 rps 💆🏽‍♀️<br><br>Dropped in LRU and now we&#39;re up to 50 rps 📈<br><br>Good—Shipit!</p>&mdash; Amjad Masad ⠕ (@amasad) <a href="https://twitter.com/amasad/status/1340108478967267329?ref_src=twsrc%5Etfw">December 19, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></p>
<p>I&#39;d like to see the dev community introduce more fun and interactivity back into building, especially when teaching new devs how to code. Most bootcamps today spend their first weeks teaching people git. But their students have no mental model for version control to be able to grok git, so it just starts on the wrong foot with people feeling inadequate or dumb for not &quot;getting it.&quot; </p>
<p>Seymour Papert called this the <a href="http://www.papert.org/articles/AnExplorationintheSpaceofMathematicsEducations.html">&quot;project/problem inversion&quot;</a>. The natural way to acquire knowledge of new tools is to have the use-case for them; today new developers are taught to cargo-cult advanced development techniques before they&#39;ve even finished learning how to code. </p>
]]></content:encoded>
            <author>amjad.masad@gmail.com (Amjad Masad)</author>
            <enclosure url="https://amasad.me/public/images/hosting.png">
            </enclosure>
        </item>
        <item>
            <title><![CDATA[Ambition++; Reflecting on a decade of work]]></title>
            <pubDate>Tue, 23 Feb 2021 00:00:00 GMT</pubDate>
            <description><![CDATA[ It's wild: Almost everything I worked on has become a great success on a global scale. I was struck by this fact earlier today when the news came out that Codecademy, where I was a founding engineer,...]]></description>
            <content:encoded><![CDATA[<p>It&#39;s wild: Almost everything I worked on has become a great success on a global scale. I was struck by this fact earlier today when the news came out that Codecademy, where I was a founding engineer, is now a <a href="https://twitter.com/amasad/status/1364296435059974149">fast-growing business</a>. The news came on the heels of our <a href="https://venturebeat.com/2021/02/18/replit-raises-20-million-for-collaborative-browser-based-coding/">Series A announcement</a> at <a href="https://repl.it">Replit</a>, where we shared some great numbers too. At Facebook, I was a founding engineer on React Native, which also had a <a href="https://shopify.engineering/react-native-future-mobile-shopify">fantastic last year</a>. And all the <a href="https://amasad.me/2016">open-source projects</a> I&#39;ve been part of --  Babel and Jest most famously -- became standard tools that measurably increased productivity and changed industries.</p>
<p>Across all my work -- the millions of developers we helped mint, the CS teachers we empowered, and the entrepreneurs we enabled -- I&#39;ve probably had a significant impact on the world economy, perhaps even meaningfully increased productivity. </p>
<p>Reflecting on this, first, I&#39;m grateful to be able to be useful on such a large scale. After all, just ten years ago, I was a kid in Amman who&#39;d just graduated from university and was interviewing at random companies (including a cigarette factory for VB6 work that comes with a free carton of cigarettes a week).</p>
<p>Second, and more importantly, I think it&#39;s time to be more ambitious. With every project, I stopped short of what was possible. I let haters &amp; doubters change my plans and assumed a sense of fake humility because that&#39;s what people expected.</p>
<p>The culmination of my work is Replit, where we&#39;re working to give people computer superpowers. We want to nudge the world away from rampant digital consumption to one where there are more creators and entrepreneurs. Anyone anywhere can participate in the digital economy and build and leverage software to better themselves and their communities.</p>
<p>Now that I&#39;ve seen what&#39;s possible in a decade while starting from nothing, in this decade, I&#39;d like to create trillions of dollars in value for the world in the form of better access to technology and tools.</p>
<p>My only regret is my mum is not here to see all this. </p>
]]></content:encoded>
            <author>amjad.masad@gmail.com (Amjad Masad)</author>
        </item>
        <item>
            <title><![CDATA[Replit is not an IDE]]></title>
            <pubDate>Tue, 15 Sep 2020 00:00:00 GMT</pubDate>
            <description><![CDATA[ When a new thing is invented, we're often stuck with the old words to define it. The first car was a "horseless carriage," and the first computer was a "giant brain." In the same inaccurate way, Repl...]]></description>
            <content:encoded><![CDATA[<p>When a new thing is invented, we&#39;re often stuck with the old words to define it. The first car was a &quot;horseless carriage,&quot; and the first computer was a &quot;giant brain.&quot; In the same inaccurate way, Replit is an &quot;online IDE.&quot;<small>[1]</small></p>
<p>Replit gets its name from &quot;REPL&quot;, the Read Eval Print Loop, a basic language tool found in most modern programming languages and environments -- a tool that allows you to interact with a program by reading, evaluating, and printing data.</p>
<p>If you imagine development environments as a continuum from REPL to IDE, you can see how Replit is located closer to the REPL end. A tool for rapidly validating concepts and exploring ideas.</p>
<p>Replit is a ultimately a reaction to the modern software development grind, where many developers spend their time waiting for builds, running tests, fighting with linters, and configuring frameworks. It&#39;s an attempt to get back to the basics of programming -- to make coding fun again.  </p>
<p>We aim to collapse the entire development lifecycle into a simple interface: write the code, 1-click, and it&#39;s live! With <a href="https://Replit/site/multiplayer">Multiplayer</a>, you can even do all this with other people in real-time. </p>
<hr>
<p><small>
[1]: It&#39;s unfortunately how we currently describe Replit on the marketing pages, which was necessary when Replit was unknown. However, this will change soon. 
</small></p>
]]></content:encoded>
            <author>amjad.masad@gmail.com (Amjad Masad)</author>
        </item>
        <item>
            <title><![CDATA[Why We Switched From MongoDB to PostgresSQL (GPT 3 post)]]></title>
            <pubDate>Wed, 29 Jul 2020 00:00:00 GMT</pubDate>
            <description><![CDATA[ _This post was generated by gpt-3. My prompt was only the title and the first sentence_  __At Tiny we're scaling really quickly__. Our platform allows tens of thousands of developers to instantly pro...]]></description>
            <content:encoded><![CDATA[<p><em>This post was generated by gpt-3. My prompt was only the title and the first sentence</em></p>
<p><strong>At Tiny we&#39;re scaling really quickly</strong>. Our platform allows tens of thousands of developers to instantly provision a running test environment in a few clicks. This creates a huge amount of data which is stored on a MongoDB cluster hosted on Google Compute Engine.</p>
<p>A few months ago we started noticing some serious performance problems. The database was not able to handle the query load. We had all of our database configuration on auto-pilot so it took us a while to realize we had a problem. After a few weeks of investigation it became obvious that MongoDB was not the right choice for us and we decided to make the switch to Postgres.</p>
<h2 id="why-we-chose-postgres">Why We Chose Postgres</h2>
<p>Postgres has been around since the dawn of the web, and is more battle tested than any other database. It has very fast performance, is open source, and runs on a wide range of platforms.</p>
<p>MongoDB has very flexible schema and is a great choice for dynamic applications. When we initially started developing our service, the schema was very flexible. Since we allow users to provision an environment in a few clicks, the data model changed from one environment to the next. This was not a problem for MongoDB. With time we became more strict in our schema and users started having a more consistent data structure, but this was now against MongoDB&#39;s strengths and caused us a lot of performance problems.</p>
<p>Postgres on the other hand has a more rigid schema. There is no auto-sharding. The database servers have to be the right size. And the sharding is much more involved to setup. There are however many open source tools that can help you monitor, optimize and scale your Postgres cluster. There are also more resources online to help you migrate from one database to another.</p>
<p>Moving to Postgres was actually very easy. All we had to do was install a few packages.</p>
<pre><code>apt-<span class="hljs-builtin-name">get</span> install postgresql postgresql-contrib postgresql-client
</code></pre><p>We had to make a few changes to our code so that it would work with Postgres&#39; strict schema.</p>
<p>We added a schema field to every model. This is important since Postgres cannot automatically detect the structure of the data.</p>
<pre><code><span class="hljs-keyword">class</span> <span class="hljs-symbol">DataContainer</span> &lt; <span class="hljs-symbol">ActiveRecord::<span class="hljs-symbol">Base</span></span> <span class="hljs-symbol">attribute</span> :<span class="hljs-symbol">schema</span> , :<span class="hljs-symbol">string</span> <span class="hljs-symbol">attribute</span> :<span class="hljs-symbol">data</span> , :<span class="hljs-symbol">text</span> , <span class="hljs-symbol">default: </span>"" <span class="hljs-symbol">end</span>
</code></pre><p>We have to explicitly define the length and format of each text field.</p>
<pre><code><span class="hljs-keyword">class</span> DataContainer &lt; ActiveRecord::Base <span class="hljs-keyword">attribute</span> :data , :<span class="hljs-type">text</span> , <span class="hljs-keyword">default</span>: "" <span class="hljs-keyword">attribute</span> :content , :<span class="hljs-type">text</span> , <span class="hljs-keyword">default</span>: "text" , size: <span class="hljs-number">25</span> .chars <span class="hljs-keyword">end</span>
</code></pre><p>Some Mongoid extensions won&#39;t work with Postgres. To convert these fields we used the ruby2ruby gem.</p>
<pre><code><span class="hljs-string">"Postgres extension for mongoid/mongo_mapper"</span> .<span class="hljs-built_in">split</span>( <span class="hljs-string">"::"</span> ).each <span class="hljs-built_in">do</span> |<span class="hljs-type">component</span>| <span class="hljs-type">mongo_model</span> = component.<span class="hljs-built_in">split</span>( <span class="hljs-string">"::"</span> ).<span class="hljs-built_in">first</span> module Mongo <span class="hljs-keyword">end</span> Mongoid::Document.extensions.each <span class="hljs-built_in">do</span> |<span class="hljs-type">extension</span>| <span class="hljs-type">if</span> extension.start_with?( <span class="hljs-string">"Mongoid::Extension::"</span> ) mongo_model_ext = extension.<span class="hljs-built_in">split</span>( <span class="hljs-string">"::"</span> ).<span class="hljs-built_in">first</span> mongo_ext = module Mongoid::Document module Extension mongo_model_ext.<span class="hljs-built_in">split</span>( <span class="hljs-string">"::"</span> ).each <span class="hljs-built_in">do</span> |<span class="hljs-type">component</span>| <span class="hljs-type">mongo_ext</span>.<span class="hljs-built_in">split</span>( <span class="hljs-string">"::"</span> ).each <span class="hljs-built_in">do</span> |<span class="hljs-type">component</span>| <span class="hljs-type">mongo_ext</span>.<span class="hljs-built_in">split</span>( <span class="hljs-string">"::"</span> ).each <span class="hljs-built_in">do</span> |<span class="hljs-type">component</span>| <span class="hljs-type">mongo_ext</span>.<span class="hljs-built_in">split</span>( <span class="hljs-string">"::"</span> ).each <span class="hljs-built_in">do</span> |<span class="hljs-type">component</span>| <span class="hljs-type">mongo_ext</span>.<span class="hljs-built_in">split</span>( <span class="hljs-string">"::"</span> ).each <span class="hljs-built_in">do</span> |<span class="hljs-type">component</span>| <span class="hljs-type">if</span> component.include?( '-is-extended-type' ) &amp;&amp; component.<span class="hljs-built_in">split</span>( <span class="hljs-string">"-"</span> ).last == <span class="hljs-string">"ruby2ruby"</span> include component.<span class="hljs-built_in">split</span>( <span class="hljs-string">"-"</span> ).last <span class="hljs-keyword">else</span> puts <span class="hljs-string">"Ignoring #{component} in mongo_extension"</span> <span class="hljs-keyword">end</span> <span class="hljs-keyword">end</span> <span class="hljs-keyword">end</span> <span class="hljs-keyword">end</span> <span class="hljs-keyword">end</span> <span class="hljs-keyword">end</span> <span class="hljs-keyword">end</span> <span class="hljs-keyword">end</span> <span class="hljs-keyword">end</span> <span class="hljs-keyword">end</span> <span class="hljs-keyword">end</span> <span class="hljs-keyword">end</span> <span class="hljs-keyword">end</span> <span class="hljs-keyword">end</span> <span class="hljs-keyword">end</span>
</code></pre><p>Adding indexes to a Postgres database is also very easy. We use data containers which contain several documents. We needed to index them by schema and id. Here&#39;s how you can create a partial index.</p>
<pre><code>rails g index add_to_container_data_schema_id

<span class="hljs-keyword">class</span> <span class="hljs-symbol">AddToContainerIndex</span> &lt; <span class="hljs-symbol">ActiveRecord::<span class="hljs-symbol">Migration</span></span> <span class="hljs-symbol">def</span> <span class="hljs-symbol">up</span> <span class="hljs-symbol">add_index</span> :<span class="hljs-symbol">containers, :<span class="hljs-symbol">schema</span>, :<span class="hljs-symbol">unique</span>: <span class="hljs-symbol">true</span></span> <span class="hljs-symbol">add_index</span> :<span class="hljs-symbol">containers, :<span class="hljs-symbol">id</span>, :<span class="hljs-symbol">unique</span>: <span class="hljs-symbol">true</span></span> <span class="hljs-symbol">end</span> <span class="hljs-symbol">def</span> <span class="hljs-symbol">down</span> <span class="hljs-symbol">remove_index</span> :<span class="hljs-symbol">containers, :<span class="hljs-symbol">id</span></span> <span class="hljs-symbol">remove_index</span> :<span class="hljs-symbol">containers, :<span class="hljs-symbol">schema</span></span> <span class="hljs-symbol">end</span> <span class="hljs-symbol">end</span>
</code></pre><p>We also need to initialize the connection with the database, otherwise Rails will try to connect to the production database.</p>
<pre><code># config/<span class="hljs-keyword">database</span>.yml production: adapter: postgresql <span class="hljs-keyword">encoding</span>: unicode <span class="hljs-keyword">database</span>: &lt;%= ENV[<span class="hljs-string">'TINY_APP_DB_NAME'</span>] %&gt; # db/structure.<span class="hljs-keyword">sql</span> # &lt;% db_name = ENV[<span class="hljs-string">'TINY_APP_DB_NAME'</span>] %&gt; # db/seeds.rb <span class="hljs-keyword">class</span> AddToContainerData &lt; ActiveRecord::Migration def up <span class="hljs-keyword">execute</span> &lt;&lt;-<span class="hljs-keyword">SQL</span> <span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">TEMP</span> <span class="hljs-keyword">TABLE</span> containers ( id <span class="hljs-type">SERIAL</span> <span class="hljs-keyword">PRIMARY KEY</span> , <span class="hljs-keyword">schema</span> <span class="hljs-type">VARCHAR</span>( <span class="hljs-number">100</span> ) <span class="hljs-keyword">NOT</span> <span class="hljs-keyword">NULL</span> , content <span class="hljs-type">TEXT</span> <span class="hljs-keyword">NOT</span> <span class="hljs-keyword">NULL</span> , <span class="hljs-keyword">FOREIGN KEY</span> (<span class="hljs-keyword">schema</span>) <span class="hljs-keyword">REFERENCES</span> schema_fields(<span class="hljs-keyword">schema</span>) ); <span class="hljs-keyword">SQL</span> <span class="hljs-keyword">execute</span> &lt;&lt;-<span class="hljs-keyword">SQL</span> <span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">UNIQUE</span> <span class="hljs-keyword">INDEX</span> containers_schema_id <span class="hljs-keyword">ON</span> containers(<span class="hljs-keyword">schema</span>); <span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">INDEX</span> containers_id <span class="hljs-keyword">ON</span> containers(id); <span class="hljs-keyword">SQL</span> <span class="hljs-keyword">end</span> def down <span class="hljs-keyword">execute</span> &lt;&lt;-<span class="hljs-keyword">SQL</span> <span class="hljs-keyword">DROP</span> <span class="hljs-keyword">TEMP</span> <span class="hljs-keyword">TABLE</span> containers; <span class="hljs-keyword">SQL</span> <span class="hljs-keyword">execute</span> &lt;&lt;-<span class="hljs-keyword">SQL</span> <span class="hljs-keyword">DROP</span> <span class="hljs-keyword">INDEX</span> containers_schema_id; <span class="hljs-keyword">DROP</span> <span class="hljs-keyword">INDEX</span> containers_id; <span class="hljs-keyword">SQL</span> <span class="hljs-keyword">end</span> <span class="hljs-keyword">end</span>
</code></pre><p>Don&#39;t forget to add the migrations to the git repository.</p>
<pre><code><span class="hljs-string">$ </span>git add db/migrate 
<span class="hljs-string">$ </span>git commit -m <span class="hljs-comment">"Adding Postgres support to the containers"</span>
<span class="hljs-string">$ </span>git push
</code></pre><p>Running our tests on Postgres took a little bit more time than running on MongoDB. It&#39;s not a lot more though. I believe this is because our test environment has to process more requests. The performance on the production server was also better than Mongo.</p>
<p>The last step we took was to set up monitoring for our Postgres cluster. We set up simple scripts that runs inside a cron job to collect data and store it in a database.</p>
<p>We&#39;re looking for smart developers. Hackers apply here!</p>
]]></content:encoded>
            <author>amjad.masad@gmail.com (Amjad Masad)</author>
        </item>
        <item>
            <title><![CDATA[Do What Makes The Best Story]]></title>
            <pubDate>Wed, 08 Jan 2020 00:00:00 GMT</pubDate>
            <description><![CDATA[ Kids are always telling themselves stories. Try to remember yourself as a child lying in bed, anticipating an exciting day tomorrow, and you'll probably remember telling yourself a story about how co...]]></description>
            <content:encoded><![CDATA[<p>Kids are always telling themselves stories. Try to remember yourself as a child lying in bed, anticipating an exciting day tomorrow, and you&#39;ll probably remember telling yourself a story about how cool it&#39;s going to be, who&#39;s going to be there, and how much fun you&#39;ll have. Self storytelling might be more pronounced in kids -- they like to say it out loud -- but it never goes away and only subsides to the background in adults. Self storytelling is so essential for people that one of the most effective <a href="https://en.wikipedia.org/wiki/Cognitive_behavioral_therapy">techniques</a> for treating depression and anxiety boils down to &quot;tell yourself better stories.&quot; </p>
<p>Life is also a form of self storytelling. We&#39;re continually retelling ourselves our life story, but very few people think of themselves as authors of their story, not mere subjects. People with extraordinary high-agency realize this early in life and start maximizing the interestingness of their life story.</p>
<p>Having a fascinating life story is not just an exercise in vanity -- it has a real impact on your success in life. You&#39;ll have an easier time attracting friends as well as life and business partners. It&#39;ll also make it much easier to sell yourself or your products. It has a kind of compounding <a href="https://en.wikipedia.org/wiki/Halo_effect">halo effect</a>.</p>
<p>Startups also have to be good stories. A good business idea or market is not enough to endure the pain and have the motivation to get a startup off the ground. Without an interesting story about the founding of the company and the vision, you&#39;ll have a hard time attracting talent and money. Notice how the most successful startups in the world all have remarkable genesis stories. </p>
<p>So next time you&#39;re faced with a tough decision, consider the path that makes a more interesting story. If it turned out to be the wrong decision to have made, you&#39;d at least be fun at dinner parties.</p>
]]></content:encoded>
            <author>amjad.masad@gmail.com (Amjad Masad)</author>
        </item>
        <item>
            <title><![CDATA[50th Anniversary of The Mother of All Demos]]></title>
            <pubDate>Sun, 09 Dec 2018 00:00:00 GMT</pubDate>
            <description><![CDATA[ I was asked to give a toast in celebration of the 50th Anniversary of [The Mother of All Demos](https://en.wikipedia.org/wiki/The_Mother_of_All_Demos) so I spent some time reflecting on Engelbart's w...]]></description>
            <content:encoded><![CDATA[<p>I was asked to give a toast in celebration of the 50th Anniversary of <a href="https://en.wikipedia.org/wiki/The_Mother_of_All_Demos">The Mother of All Demos</a> so I spent some time reflecting on Engelbart&#39;s work. </p>
<p>Most of the commentary on his work is focused on the technical achievements and the impressive feats of engineering that&#39;s genuinely 50 years ahead of its time. Just this week we, at Repl.it, we introduced Multiplayer -- the ability to code together with anyone in the world -- and although we have the benefits of modern tooling and infrastructure it was still hard work</p>
<p>A more interesting question to ask would be: &quot;What&#39;s Douglas Englebart&#39;s generation function?&quot; In other words, what ideas, themes, and philosophies that have inspired his groundbreaking work?</p>
<p>I didn&#39;t have much time to work with, so I had to go mostly of off memory -- this question requires a more in-depth examination. However, I&#39;ve identified three themes that are worth studying. </p>
<h2 id="computers-as-mind-extenders">Computers as mind extenders</h2>
<p>Engelbart and his contemporaries saw computers as first and foremost tools for mind extension. Something we can use to augment our intellect to take on more and do more. </p>
<blockquote>
<p>&quot;By augmenting human intellect we mean increasing the capability of man to approach complex problem situation to gain comprehension to suit his particular needs and to derive solutions to problems. Increased capability in this respect is taken to mean mixture of the following: more rapid comprehension, better comprehension, the possibility of gaining useful degree of comprehension in situation that previously was too complex, speedier solutions, better solutions and the possibility of finding solutions to problems that before seemed insoluble.&quot; -- <a href="https://www.dougengelbart.org/pubs/papers/scanned/Doug_Engelbart-AugmentingHumanIntellect.pdf">Augmenting Human Intellect</a></p>
</blockquote>
<p>This sits in stark contrast to today&#39;s computers as the driver for the attention economy. Where computers as seen as entertainment devices at best. A more cynical reading of the way governments and ad-based businesses use computers would lead you to believe they&#39;re devices of control.</p>
<h2 id="evolutionary-design">Evolutionary design</h2>
<p>To understand Engelbart it&#39;s important to not view him as a lone inventor genius a la Tesla that predicted what computers could do 50 years ahead of his time. In his own words you can see that they took a much more exciting approach to discovery:</p>
<blockquote>
<p>&quot;We&#39;re pursuing this monstrous goal by building and trying <em>empirically</em> -- we approach evolutionary-wise because we feel it&#39;s a whole system problem [...] it&#39;s much more than these computer tools&quot;</p>
</blockquote>
<iframe width="560" height="315" src="https://www.youtube.com/embed/agdPQuFr0yg" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

<h2 id="bootstrapping">Bootstrapping</h2>
<p>&quot;Bootstrapping&quot; is another recurring theme in Engelbart&#39;s work. I think of it as &quot;increasing returns&quot;:</p>
<ul>
<li>You build tools, and then the tools you built helps you create better tools. </li>
<li>Tools make you smarter, and you make better tools that make you smarter... ad nauseam. </li>
<li>Tools increase productivity which makes us wealthier which in turn allows us to invest in more and better tools.</li>
</ul>
<h2 id="conclusion">Conclusion</h2>
<p>It&#39;s worth noting that what seemed to drive Engelbart was his concern for the unique challenges an exponentially changing world brings. He believed that <a href="https://www.dougengelbart.org/pubs/papers/scanned-original/2004-augment-133319-augmenting-society&#39;s-collective-iqs.pdf">&quot;boosting Collective IQ&quot;</a> is imperative for the flourishing of humanity.</p>
<p>In Silicon Valley, at least in my circles, there&#39;s a general feeling that we need to return to the thinking of computers as &quot;bicycles for the mind.&quot; And I hope we do.</p>
<p><em>Thanks to Figma and Dylan Field for inviting me to <a href="https://www.meetup.com/Figma-SF/events/cwsnhqyxqbmb/">reflect</a> on this awesome day.</em></p>
]]></content:encoded>
            <author>amjad.masad@gmail.com (Amjad Masad)</author>
        </item>
        <item>
            <title><![CDATA[Leapfrogging the IDE]]></title>
            <pubDate>Sun, 11 Nov 2018 00:00:00 GMT</pubDate>
            <description><![CDATA[ Progress in technology happens incrementally; it's hard to imagine inventing the cellphone without inventing landline telephones first. However, adoption need not respect the incremental nature of in...]]></description>
            <content:encoded><![CDATA[<p>Progress in technology happens incrementally; it&#39;s hard to imagine inventing the cellphone without inventing landline telephones first. However, adoption need not respect the incremental nature of innovation. Advanced technology is often easier to adopt because it requires less infrastructure.</p>
<p>The classic example of this is the astonishing adoption of mobile in Africa especially relative to landline:</p>
<p><img src="/public/images/africa.jpg" alt="mobile vs fixed in africa"></p>
<p>Sometime last year we discovered that some users use <a href="https://repl.it">Repl.it</a> -- an online REPL and development platform -- as their primary programming tool. This seems surprising at first: other than for learning, why would anyone use a more limited tool over a more mature and flexible one?</p>
<p>It turns out this was the wrong question to ask. A better one would be: &quot;if someone had already learned to code on an online REPL and it serves their needs then why would they want to invest in a local setup?&quot;. Because they&#39;d started with Repl.it, they need a compelling reason to install an IDE locally and possibly have to invest in buying a more expensive device (say from a Chromebook to a Mac).</p>
<p>In fact, this is the exact question our users are <a href="https://repl.it/talk/ask/Can-Replit-substitute-a-code-editor-like-PyCharm/6245">asking</a>: why do I have to switch?</p>
<p><hr/>
<img src="/public/images/primary.png" alt="replit as primary coding"></p>
<hr/>

<p>This way of formulating questions better explains the leapfrogging phenomenon in general: &quot;why do I have to invest in a PC if my tablet/mobile handles all my computing needs?,&quot; &quot;why do I need a credit-card if I can just use my mobile payment wallet?&quot; etc.</p>
<p>In our experience, even the people that make the switch are often dissatisfied with the result -- wishing VSCode  worked just like Repl.it:</p>
<p><hr/>
<img src="/public/images/vscodereplit.png?x=1" alt="vscode user not happy"></p>
<hr/>

<p>With programmers growing up today being used to instant, interactive, globally accessible programming tools like Repl.it, Jupyter Notebooks, serverless (pay-as-you-go) compute, and others, it doesn&#39;t seem so outlandish to imagine a post-IDE world.</p>
<p>_This blog is built and hosted with Repl.it: <a href="https://replit.com/@amasad/my-blog">amasad.me/__repl</a></p>
]]></content:encoded>
            <author>amjad.masad@gmail.com (Amjad Masad)</author>
        </item>
        <item>
            <title><![CDATA[Beware the Metagame]]></title>
            <pubDate>Sun, 11 Nov 2018 00:00:00 GMT</pubDate>
            <description><![CDATA[ Have you ever wondered why the less "pure" a scientific field is, the less progress we've made?  ![](https://imgs.xkcd.com/comics/purity.png)  The more abstract a subject is, the easier it is to reas...]]></description>
            <content:encoded><![CDATA[<p>Have you ever wondered why the less &quot;pure&quot; a scientific field is, the less progress we&#39;ve made?</p>
<p><img src="https://imgs.xkcd.com/comics/purity.png" alt=""></p>
<p>The more abstract a subject is, the easier it is to reason about and therefore make progress on. That&#39;s why we&#39;ve made a lot more progress in math and physics than any other subject. The problem became more salient recently as some of the perceived scientific progress made in the less pure sciences -- psychology, medicine, economics -- is being nullified in a widespread <a href="https://en.wikipedia.org/wiki/Replication_crisis">&quot;replication crisis&quot;</a> where many scientific studies are failing to reproduce.</p>
<p>One way to get more abstract is to take the meta view of a subject. Programming Language Theory (PLT), for example, is the study of programming languages and their features and characteristics. While a lot of progress has been made in PLT, rarely does this translates into features in languages used in the real world. There&#39;s often decades-long gap for some form of a PLT idea to make to the industry because programming is messy and complicated and full of human problems that PLT researchers don&#39;t bother studying.</p>
<p>I have a lot more respect for people who stick to the base game, avoiding getting sucked into the much more comfortable metagame. While we need researchers and scientists to go meta, they should remain tethered to the base-game and work closely with practitioners.</p>
<p>I&#39;ve first noticed this problem in the startup world where you see famous people that sell books, talk at conferences, and tweet advice to founders, but when you take a closer look, they&#39;ve never done much founding themselves. They&#39;re like the &quot;entrepreneurship&quot; professor that never built a business. They&#39;re experts in the metagame -- they&#39;re polished speakers, engaging writers, and thought-leadering tweeters. The problem, though, is that they&#39;re not judged by customers, the market, or nature, instead they&#39;re judged by their peers. I call them metapreneurs.</p>
<p>This is an instance of what Nassim Taleb calls &quot;The Expert Problem&quot; -- when other experts and meta-experts judge experts. Eventually the lack of contact with reality will corrupt the field. In the sciences, that lead to the replication crisis and the <a href="https://areomagazine.com/2018/10/02/academic-grievance-studies-and-the-corruption-of-scholarship/">absurdities</a> of the humanities.</p>
<p>If you find yourself going to a lot of conferences, opining too much on the latest fad in your field, and talking more about doing the thing than doing the job itself, then you, my friend, are getting sucked into the metagame.</p>
]]></content:encoded>
            <author>amjad.masad@gmail.com (Amjad Masad)</author>
        </item>
        <item>
            <title><![CDATA[Github and Open-source Is a Boon for the Underprivileged]]></title>
            <pubDate>Sat, 09 Jun 2018 00:00:00 GMT</pubDate>
            <description><![CDATA[ I was born to immigrant parents. My mother's family left Algeria looking for a better life in Syria and then Jordan (where I was born). On my father's side, his family fled the war in Palestine to Sy...]]></description>
            <content:encoded><![CDATA[<p>I was born to immigrant parents. My mother&#39;s family left Algeria looking for
a better life in Syria and then Jordan (where I was born). On my father&#39;s side,
his family fled the war in Palestine to Syria and then settled in Jordan. My father&#39;s family was so poor that he had to sleep with ten
other children in the same room (his brothers and his brothers&#39;
children). Luckily, Palestinians, for whatever reason, valued education above
everything else, so they made sure to save up to send my father to Turkey
(because there were no universities in Jordan at the time) to study to
become an engineer.</p>
<p>When my father came back to Jordan, he worked for the government as an engineer. There, he
faced discrimination because government jobs were typically reserved for
natives. Despite all this, he rose in the ranks for years until he became the
city manager of Amman, the capital of Jordan. My father&#39;s journey taught me
that as someone who&#39;s underprivileged or discriminated against you need to work
ten times harder than the next person to get ahead. You need to leverage
whatever tool you have to signal that you&#39;re great at your job. For him, it was his reputation. In a country ravaged by corruption my
father had a reputation for being so straight it baffled people (but it also
meant that we wouldn&#39;t get to see any of that corruption money, and we had to
grow up on a measly government salary).</p>
<p>Which brings me to the recent debate in the developer community on using GitHub
as a résumé. While I try to stay away from debating hot topics because it takes time to form an informed opinion, this was a subject that&#39;s near
and dear to my heart, so I had to write about it.</p>
<p>It all started with this tweet claiming that GitHub is the only way that
employers can validate talent.</p>
<blockquote class="twitter-tweet" data-lang="en"><p lang="en" dir="ltr">10/ GitHub is the de facto source for validating top talent the world over.<br><br>Résumé or CV? <br><br>Please.<br><br>Show me your GitHub profile, commits you've landed, projects you've forked, code you've released.</p>&mdash; Joe McCann (@joemccann) <a href="https://twitter.com/joemccann/status/1004798006485573632?ref_src=twsrc%5Etfw">June 7, 2018</a></blockquote>

<p>While I disagree with this statement, I found myself also disagreeing with
people on the other side of the debate which, in my opinion, are also staking
out an extreme position. They&#39;re <a href="https://twitter.com/EricaJoy/status/1004849360625168384">saying</a> that GitHub is not only a &quot;useless
signal&quot; but is also discriminatory by nature. (I found
myself agreeing more with moderate positions like Kim&#39;s
<a href="https://twitter.com/KimCrayton1/status/1005098820731097088">here</a> saying that basically, employers are shooting
themselves in the foot by excluding people with no GitHub profiles).</p>
<p>Starting with the assumption that employers would want to hire the best candidates for
the job[1], we can observe that they&#39;re
merely trying to navigate the problem of &quot;adverse selection,&quot; which occurs in any
market where there exists an asymmetry of information. Because candidates can deceptively
spruce up
their resumes and maybe even rise in the corporate ladder by being gifted at
office politics, and because most good programmers are not in the job market
(they either have a job or get headhunted before they enter the market), this
leaves employers in a tricky position with an insufficient set of tools to evaluate
candidates (see <a href="https://en.wikipedia.org/wiki/The_Market_for_Lemons">The Market for
Lemons</a> for an interesting
discussion on adverse selection). GitHub, on the other hand, cuts through the
bullshit (for the most part).</p>
<p>You can fake a resume, or end up with a good one simply as a function of
your privilege. For example, if you&#39;re born into wealth,
your parents can probably call in favors to get you jobs at prestigious
companies. But can you really fake GitHub profile? It&#39;s tough to do so,
and that&#39;s because the &quot;screening&quot;, as it were, is done by OSS maintainers. You
can&#39;t bullshit your way into getting pull requests landed. And no matter your parent&#39;s
standing in society, if your code stinks, you can&#39;t contribute. This makes GitHub a
precious tool for recruiters.</p>
<p>Because open-source is good at cutting through the bullshit, it also makes it an equalizer. If you come from an
underprivileged background, you should absolutely use GitHub to get ahead. That&#39;s
exactly what I did. I owe my entire career to open-source.</p>
<p>Back in college, I didn&#39;t have a personal computer, and I was always on the
move -- from campus to the office, to home. Which made it tough to code
on projects, or solve homework because every time I got my hands on a computer, I
needed to setup the development environment. So I started dreaming about a world
where I can open a browser tab and start coding, in any language,
anywhere. Which started a multi-year project to build an in-browser repl. The
first thing I did was put a textarea with a button that <code>eval</code>d JavaScript. I was
able to program on my Nokia phone and work on problems on the go. But I wanted
this experience to be better and to work for more languages.</p>
<p><a href="https://news.ycombinator.com/item?id=16578943">Long story</a> short, years after I
had the idea for an online repl was I able, with help from
friends, to build the first polyglot <a href="https://github.com/replit/jsrepl">in-browser repl</a> along with a <a href="https://github.com/replit/jq-console">web terminal</a>
implementation. I tried to start a company around this idea, but nobody would
fund me. Luckily, everything was open-source on GitHub and soon after we
released the project I saw that not only one, or two, but more than a dozen
companies in Silicon Valley started using our software.</p>
<p>Although I had applied so many times to work at Google, Facebook, and many
others, I never got a response back, let alone an interview. Open-source became
my ticket there. I joined Codecademy as the #1 employee and helped 10s of millions
of people to learn how to code.</p>
<p>Afterward, I joined Facebook to try and work at the team behind React.js. But I
was stuck working on the photos product (which I couldn&#39;t care less for) because
the React team was one of the hottest teams at the company. So
I started contributing to their open-source projects. I know it sounds crazy and
roundabout, but I was able to prove myself more via my GitHub contributions than my
day job. I think that played a big part in letting me in the team where I worked on
React Native.</p>
<p>Today, I&#39;m trying to pay it forward. At my new company, <a href="https://repl.it">Repl.it</a>, we believe that
programming is a great equalizer. We&#39;ve seen our product used by <a href="https://repl.it/site/blog/refugees">refugees</a> to
learn how to code. By people to <a href="https://repl.it/site/blog/two_stories">upgrade</a>
their careers and land tech jobs and to
<a href="https://repl.it/site/blog/two_stories">teach</a> low-income high-achieving children how to code. Or by <a href="https://www.reddit.com/r/learnpython/comments/54d53z/help_a_homeless_man_code_again/">homeless</a> people who
only have access to computers at the public library. At this point, we&#39;ve heard enough &quot;rags to
riches&quot; stories in programming that it becomes difficult to dismiss this as
simply &quot;survivorship bias&quot;.</p>
<p>To conclude: if you come from an
underprivileged background then the unfortunate reality of the situation is that
you&#39;re going to have to work harder than everyone else. And you&#39;re going to want
to use any tool at your disposal, like Github, to signal that you&#39;re you going
to be great at your job so you can land great jobs.</p>
<p>If you need advice, I&#39;d be happy to help, my DM are open on <a href="https://twitter.com/amasad">twitter</a>.</p>
<hr>
<p><small>
[1]: It&#39;s still a safe assumption to start with, even if it&#39;s not entirely
accurate. Even if you believe that bigotry (or unconscious bias) plays a big part in
excluding people, I think that from a first-person point of view, you can&#39;t control
that. For example, it&#39;s hard for me as an individual Muslim to change the fact
that some people hate Muslims, so it&#39;s better for me to focus my energy on
things that I can control. This, however, doesn&#39;t mean that as a society we shouldn&#39;t discuss issues of
discrimination.
</small></p>
]]></content:encoded>
            <author>amjad.masad@gmail.com (Amjad Masad)</author>
            <enclosure url="https://cdn-images-1.medium.com/max/1600/1*lBVMxcsvMHSkghlAo1-5GQ.png">
            </enclosure>
        </item>
        <item>
            <title><![CDATA[Be Grateful]]></title>
            <pubDate>Sat, 02 Jun 2018 00:00:00 GMT</pubDate>
            <description><![CDATA[ Where I'm from "Thank God" is something you say every day. While nowadays most people say it in an automatic, mindless way, I think it came to be tradition because of a profound sense of appreciation...]]></description>
            <content:encoded><![CDATA[<p>Where I&#39;m from &quot;Thank God&quot; is something you say every day. While nowadays most
people say it in an automatic, mindless way, I think it came to be tradition
because of a profound sense of appreciation for life by our ancestors. People
found themselves in a world where things are not too bad and often pretty
good. They looked around them, and while they didn&#39;t know why or how they got
here, they felt thankful for the life they&#39;re given. So they felt and expressed
gratitude, multiple times day, each day.</p>
<p><em>&quot;We are going to die, and that makes us the lucky ones&quot;</em> said Richard Dawkins,
talking about how lucky we are to be the ones that got to live for <em>&quot;the
potential people who could have been here in my place but who will in fact never
see the light of day outnumber the sand grains of Arabia&quot;</em>. Meditate on that,
and when you feel those words, no matter what your misfortune is, you&#39;ll know
that you&#39;re damn lucky to be alive.</p>
<p>In the story, <em>Candide: Optimism</em>, a philosopher named Pangloss believed that we
live in the best of all possible worlds. And despite the deep misfortune visited
upon him–enslavement, torture, earthquakes, and more–Pangloss maintained his
belief that he lives in the best of all possible worlds. While the story is
ridiculing this type of thinking, I think there&#39;s something to be learned from
Pangloss. We may not be living in the best of all possible worlds, but I can
certainly imagine far worse worlds than I can imagine better ones. Maybe that&#39;s
because we humans are wired to fear the worst so we can survive the world. But
the flipside is that you can be deeply grateful for living in a world where your
deepest fears are not reality.</p>
<p>So I&#39;m thankful. Starting with my peaceful upbringing, I&#39;m beholden to my
parents and my grandparents who left war-ravaged countries to move to an island
of peace among total and utter nihilistic destruction. I grew up in an
intellectually and physically stimulating environment. And for that, I&#39;m
grateful to my friends, teachers, and peers. I&#39;m thankful for my hometown, the
place where I found love–a woman that believed in me and pushed me to my limits
and beyond.</p>
<p>However, I chose to leave to follow in the footsteps of my heroes. To the place
where pioneers, inventors, and visionaries imagined and built a world where
humans can transcend their limitations. Extended by technology, we&#39;re evolving
into something new and beautiful. I&#39;m grateful to the country that took me in,
the industry that let me follow my dreams, and the people that took a bet on me.</p>
<p>Yes, I know I&#39;m lucky, and that&#39;s precisely why I&#39;m thankful. But I also believe
in progress. I think that we–all of us, all of humanity–are going somewhere,
somewhere beautiful. So be thankful; be thankful for every moment you&#39;re
alive. And if you&#39;re also one of the lucky ones, you have a responsibility to
make the world a little better for everyone else.</p>
<p>Thank you for reading this.</p>
]]></content:encoded>
            <author>amjad.masad@gmail.com (Amjad Masad)</author>
        </item>
        <item>
            <title><![CDATA[Mental Frames to Get Over Entrepreneurial Anxiety and Depression]]></title>
            <pubDate>Thu, 31 Aug 2017 00:00:00 GMT</pubDate>
            <description><![CDATA[ Would you accept a gamble that offers a 10% chance to win $95 and a 90% chance to lose $5?    Would you pay $5 to participate in a lottery that offers a 10% chance to win $100 and a 90% chance to win...]]></description>
            <content:encoded><![CDATA[<p>Would you accept a gamble that offers a 10% chance to win $95 and a 90% chance
to lose $5?</p>
<p>Would you pay $5 to participate in a lottery that offers a 10% chance to win $100 and a 90% chance to win nothing?</p>
<p>Chances are the second proposition sounded more appealing to you. But look
again, both these propositions are identical. The second version
attracts more positive answers[1] because it&#39;s <em>framed</em> as cost whereas the
first version is <em>framed</em> as a loss and who wants to lose?</p>
<p>This is called &quot;framing effects,&quot; how something is presented colors how we think
about it. Similarly how we interpret the world around us and our situation in it
would affect how we feel and act. In fact, there are whole branches of
psychotherapy that focus on the art of viewing things differently: &quot;positive
reframing&quot;, &quot;cognitive reframing&quot;, and &quot;cognitive restructuring&quot;. However, what
I&#39;d like to focus on is dealing with specific set issues, issues that have
to do with creating something new in the world, building a business, and all
the turmoil that brings.</p>
<p>When you&#39;re a startup founder, it&#39;s almost like your mood is tied to your
metrics. When your company is doing well, you feel great. When your company
isn&#39;t doing so hot, you&#39;re feeling bad. This, in turn, will affect your
productivity and may set you on a vicious cycle of doom where your company isn&#39;t
doing well, and you don&#39;t have the energy to fix it.</p>
<p>So how do you escape this, deal with the stress, take action on it, and have
some fun doing it? Well, we can exploit the mental bug that is &quot;framing effects&quot; to bring about a better state of
mind. I&#39;ll introduce what I call &quot;mental frames&quot;[2] -- I&#39;m not sure if that&#39;s a real
technical term, but it sounded good to my ears -- that has helped and continues
to help me get through tough times.</p>
<p>Before I start, I want to acknowledge that it feels kind of silly that we have to trick
ourselves and tell ourselves stories to act the way that we want to
act. The reason we have to do this is that more and more we&#39;re discovering that we&#39;re not just one
self, we&#39;re multiple ones. Scientists and philosophers, in different contexts, have proposed various theories on the division of the self. There is the momentary vs. the narrating self; there is System 1 vs.
System 2; there is the left vs. the right hemisphere; there is the lizard
brain vs. the neocortex. All that goes to show that although there is a part of your self that wants to get better at managing your mental states -- the one that&#39;s reading this, hi! -- it doesn&#39;t automatically mean that all your selves are onboard. So join me on a journey to trick these bastards to do what you want.</p>
<p><em>Also, I&#39;m not a mental health specialist, see one if you need to.</em></p>
<h2 id="life-is-a-game-mental-frame">&quot;Life is a game&quot; mental frame</h2>
<blockquote>
<p>Once a motherfucker get an understandin&#39; on the game, and what the levels and
the rules of the game is, then the world ain&#39;t no trick no more, the world is a
game to be played.</p>
<p>-- 2Pac in &quot;Starin&#39; Through My Rear View&quot;</p>
</blockquote>
<p>Part of the startup game is taking risks, in fact, it&#39;s almost the only game in
town. If you&#39;re not taking risks, then your startup already exists, and you&#39;re
just copying something else. But if you are creating something new in the world
there wouldn&#39;t be a week that goes by without feeling anxiety about all the risk
that you&#39;re taking. Be it your career, other people&#39;s times and money, or
with your product, users, etc.</p>
<p>The risk anxiety can paralyze you and unless you act you&#39;re just making your
situation worse. One handy mental frame to adopt in this case is &quot;life is
a game, and I&#39;m playing it.&quot; If life is a game, then you&#39;re there to play it. When
you&#39;re, for example, playing a video game, although you stop to weigh the pros and cons of every decision you
make, in the end, you have to act. Otherwise, nothing will happen, and it&#39;s no fun. You&#39;ll happily
jump from place to place, explore different areas, try different combinations of
keys or moves. You&#39;re never standing still,
always making decisions and executing, learning, failing, restarting and going again.</p>
<p>The &quot;life is a game&quot; mental frame puts you in a fun frame of mind. You just
can&#39;t wait to see what happens next. Maybe you&#39;ll lose, perhaps you&#39;ll win --
who cares! As long as it&#39;s interesting, keeps you amused, engaged, and learning.</p>
<h2 id="time-keeps-moving-forward-mental-frame">&quot;Time keeps moving forward&quot; mental frame</h2>
<blockquote>
<p>I was a little bit of a procrastinator and I would be faced with this seemingly
insurmountable task. I have final exams, I have massive amounts of work, papers
-- there is no way to make it through. At that time -- and this is served me
well -- I would say &#39;well, one way or another time keeps moving forward so
even though I&#39;m just three weeks away, whatever happens in three weeks from now
I&#39;ll be on the other side&#39;. So it seems like a wall that I can&#39;t get through but
actually time is marching ahead and I will get to that point past that thing
automatically and that was helpful to me.</p>
<p>-- Siri, Change.org, and Viv founder Adam Cheyer on the &quot;Finding Mastery&quot;
podcast.</p>
</blockquote>
<p>When you have an upcoming deadline or a significant date of somesort -- be it a product
launch, scoring a deal, hiring someone, or the end of your runway -- there is no
real rational reason to feel anxious. All you have to do is perform your best,
and the rest is outside your control.</p>
<p>In situations where it&#39;s painful, you have to remember that
time will go by, nothing lasts forever, and that you&#39;ll eventually be on the other side. What&#39;s
important now is to execute!</p>
<h2 id="worst-case-scenario-mental-frame">&quot;Worst-case scenario&quot; mental frame</h2>
<p>You might&#39;ve used this one before; it&#39;s kind of a cliche that&#39;s often used out
of place: &quot;order the pizza, worst-case
scenario we&#39;ll eat it in the car&quot; or some such thing.</p>
<p>When correctly used, it can be compelling. Right now, think about a difficult
situation in your life, or a tough decision you&#39;re pondering, or a
risky move you&#39;re considering. Now think about the <em>absolute</em> worst thing that can
happen as a result of your actions -- like literally the worst thing:</p>
<ol>
<li>Will someone die?</li>
<li>Will someone get seriously injured?</li>
<li>Will you become homeless and starve on the streets?</li>
<li>Will you lose your house/job/car?</li>
<li>Will you tarnish your reputation?</li>
<li>Will you fail at the startup thing and go back a to a cushy job where
they feed and do your laundry?</li>
</ol>
<p>Etc. Barring #1, #2, and #3 I think everything else can be tolerated. Honestly
for most decisions at Silicon Valley startups that may lead to ruin, it&#39;s probably going to be #5 that ends
up being the worst-case scenario, and you know it&#39;s not all that bad.</p>
<p>A excellent technique to couple with the worst-case scenario mental frame is what&#39;s
called &quot;negative visualization&quot;. An age-old technique invented by the Stoics in ancient Greece,
you visualize or meditate on the worst. Like, actually imagine it happening. If it does happen, you&#39;re already at peace with it, and if
good or neutral thing happens then it&#39;s ecstatic!</p>
<h2 id="you-re-not-your-job-mental-frame">&quot;You&#39;re not your job&quot; mental frame</h2>
<p>&quot;Founder of [insert sexy startup name]&quot; is what you have on your twitter bio. It seems like this
thing is intricately intertwined with your identity. But in reality, you&#39;re a
lot more than that. You might be a good husband/father/son. You
might be a good thinker, writer, or educator. Or you might have hobbies that you&#39;re
good at.</p>
<p>When failure strikes, you might feel that you, personally you, are a failure -- which
is basically depression. When that happens, remind yourself that you&#39;re much more than your
job -- that you contain multitudes.</p>
<p>It&#39;s good to cultivate other interests, hobbies, or anything that you
can get good at. Have people that rely on you outside of your work. Mentor
someone. Learn a new skill. Find a hobby. Whatever you do try to link it to your
identity.</p>
<p>For me, I try to always have someone that I&#39;m mentoring. I read, discuss, and dabble in
doing philosophy. I&#39;m currently obsessed with weight-lifting. I also like to get
better at writing, public speaking, and storytelling. I love to optimize my
health. This year I spent a lot of time enhancing my sleep. Going from an
average 5 hours a night to 7.5 hours a night. I also increased my REM sleep,
going from less than an hour to 1.5-2.5 hours.</p>
<h2 id="what-did-i-learn-mental-frame">&quot;What did I learn&quot; mental frame</h2>
<p>If you&#39;re the kind of type A personality that would choose the entrepreneurial
path then chances are, you like self-improvement, and chances are, you love
learning. So when failure does catch up with you then do yourself a
favor and think about everything that you&#39;ve learned from your experience.
Maybe even write about it but, at all costs, avoid titling your post <a href="https://ourincrediblejourney.tumblr.com/">&quot;our wonderful journey.&quot;</a></p>
<hr>
<p>There is a lot more to this, and I&#39;ll try to keep this as a live document. But
for now, I need to get back to playing the life game because time won&#39;t wait for
me, and really, what&#39;s the worst that can happen? I want you to remember
though, that I&#39;m not only my job, it&#39;s true that I learn a lot from it, but I
contain multitudes!</p>
<hr>
<p><small>
[1] Kahneman, Daniel. Thinking, Fast and Slow (p. 364). Farrar, Straus and
Giroux. Kindle Edition.</p>
<p>[2] I know of &quot;mental models&quot; but for some reason it didn&#39;t quite fit. There is
some overlap, however, where mental models is primarily about making intelligent
decisions, mental frames is about managing your own psyche.</p>
<p></small></p>
]]></content:encoded>
            <author>amjad.masad@gmail.com (Amjad Masad)</author>
        </item>
        <item>
            <title><![CDATA[Dialectical Progress in Programming]]></title>
            <pubDate>Sat, 27 May 2017 00:00:00 GMT</pubDate>
            <description><![CDATA[ The notion of progress in programming is -- as in anything else -- debatable and hard to define. For various reasons that are besides the point of this essay I believe that we're indeed making progre...]]></description>
            <content:encoded><![CDATA[<p>The notion of progress in programming is -- as in anything else -- debatable and
hard to define. For various reasons that are besides the point of this essay I
believe that we&#39;re indeed making progress in the art of programming (otherwise
what&#39;s the point in getting up in the <s>morning</s> afternoon and going to the
office?).</p>
<p>But how does progress happen in programming? Sometimes it looks like it&#39;s an
arbitrary walk in the space of possible languages, frameworks and
architectures. I&#39;d like to propose an answer: <em>programming progresses
in <a href="https://en.wikipedia.org/wiki/Dialectic">dialectical</a> fashion</em>. Meaning what usually follows the current best
practices and technologies is an opposite in many ways. However, this is usually
followed by a <em>synthesis</em> of these two opposites. In other words, a compromise
or a <em>best of both worlds</em>.</p>
<p>We can think of this as a <a href="https://en.wikipedia.org/wiki/Thesis,_antithesis,_synthesis"><em>thesis, antithesis, synthesis</em></a>:</p>
<blockquote>
<p>(1) a beginning proposition called a thesis, (2) a negation of that thesis
 called the antithesis, and (3) a synthesis whereby the two conflicting ideas
 are reconciled to form a new proposition.</p>
</blockquote>
<p>Let&#39;s look at some examples.</p>
<h3 id="languages-industrial-strength-vs-developer-friendliness">Languages: industrial strength vs developer friendliness</h3>
<ol>
<li><p>Thesis: <strong>industrial strength programming languages</strong>. Languages like Java
and C++ are type-safe, efficient and work well with large systems. But they&#39;re
also hard, boring, noisy, and take a long time to compile.</p>
</li>
<li><p>Antithesis: <strong>developer friendly languages</strong>. Languages like JavaScript,
Python, and Ruby are dynamically typed so the syntax is clean and less
noisy. They&#39;re interpreted so there is no compiler to wait for. And they&#39;re fun
and arguably more productive to work with.</p>
</li>
<li><p>Synthesis: <strong>developer friendly and suitable for large scale
programming</strong>. Languages like Go, Rust, and TypeScript are both type-safe,
efficient and work well at large scales.</p>
</li>
</ol>
<h3 id="web-rendering-server-rendered-vs-client-rendered-pages">Web rendering: server-rendered vs client-rendered pages</h3>
<ol>
<li><p>Thesis: <strong>server-rendered pages</strong>. Languages and frameworks powering Web 2.0
like PHP and Ruby on Rails can get you to market quickly, with predictable
performance, and works well with the rest of the web infrastructure (links,
search engines etc).</p>
</li>
<li><p>Antithesis: <strong>client-side rendered pages</strong>. Frameworks like Backbone, React,
and Angular can create delightful user experiences. But they break the web&#39;s
protocol (hypertext over TCP) and can be slow to boot up.</p>
</li>
<li><p>Synthesis: <strong>universal rendering</strong>. Frameworks like <a href="https://github.com/zeit/next.js/">Next.js</a> bring us the best
of both worlds: a great user experience, great initial render time, and great
support for search engines and other web infrastructure.</p>
</li>
</ol>
<h3 id="mobile-apps-native-vs-web">Mobile apps: native vs web</h3>
<ol>
<li><p>Thesis: <strong>web applications</strong>. Web 2.0 unleashed the power of the internet and
brought us amazing applications like social networking and YouTube. But
when mobile came around, using web tech to build mobile apps created monstrosities
like the first Facebook HTML5 app.</p>
</li>
<li><p>Antithesis: <strong>native applications</strong>. Native applications brought much better
user-experience with gesture support, smooth scrolling, and access to APIs
like location and notifications. However, a lot of progress that we made in
engineering (e.g. continuous deployment, cross-platform development) or in application distribution (just
visit a URL) had to be thrown away.</p>
</li>
<li><p>Synthesis: <strong>progressive web apps and web tech adapted to native</strong>. PWAs
and frameworks like React Native bring us the best of both worlds. Access to
native (or native-like) APIs and a great user experience but also cross-platform
development, continues deployment and better application distribution
strategies.</p>
</li>
</ol>
<h3 id="conclusion">Conclusion</h3>
<p>This framework of thinking about progress in programming seems to apply to a lot
of what I see happening in programming. There are ongoing developments that I
look forward to seeing the synthesis of:</p>
<ul>
<li><strong>Web development build tools</strong>: we started out writing and loading scripts
in the browser verbatim but applications getting more complicated lead
us to build better languages and frameworks which lead us to
introduce ever more complicated build-steps to our web developement and
deployment pipelines. However, with browser vendors moving faster on supporting
language features and with framework authors acknowledging the problem I think
we&#39;re going to see a synthesis soon.</li>
<li><strong>IDEs</strong>: when I first started programming it seemed unquestionable that you
needed to use an IDE. However, they were slow and bloated. And with the shift
towards more dynamic languages there was also a shift towards pure text
editors like Textmate and Sublime and a return to Vim and Emacs. However,
with editors like Atom that has a richer-than-ever plugin ecosystems it seems
like we&#39;re headed in a synthesis direction where we use lightweight editors
while plugging in static analysis, autocompletion, and other automation tools.</li>
</ul>
<p>There are a lot more industry trends that can be described and understood using
the dialectical framework of progress. I&#39;d be curious to hear your thoughts
on this and if you think if this framework applies to trends in your programming
community. I&#39;m best reachable on <a href="https://twitter.com/amasad">twitter</a>. Thanks for reading.</p>
]]></content:encoded>
            <author>amjad.masad@gmail.com (Amjad Masad)</author>
        </item>
        <item>
            <title><![CDATA[Disintegrated Development Environments — How Did We Get Here?]]></title>
            <pubDate>Mon, 01 May 2017 00:00:00 GMT</pubDate>
            <description><![CDATA[ [_This essay is an adaptation of my talk at [Active Ingredients Conference](http://activeingredients.info/)_]  It's never been better for programmers, a team of 5 today can build projects and compani...]]></description>
            <content:encoded><![CDATA[<p>[<em>This essay is an adaptation of my talk at
<a href="http://activeingredients.info/">Active Ingredients Conference</a></em>]</p>
<p>It&#39;s never been better for programmers, a team of 5 today can build projects and
companies that required hundreds if not thousands of engineers just a few
decades ago. So although Fred Brooks was right in that there was &quot;no silver
bullet&quot; which &quot;by itself promises even an order of magnitude improvement in
productivity&quot; I&#39;d argue that there was a million silver arrows that collectively
got us those improvements.</p>
<p><img src="/public/images/no_silver.jpeg" alt="No Silver Bullet"></p>
<p>Much of this came through open source software, development tools and open
source development tools.</p>
<p><img src="/public/images/silver_arrows.jpeg" alt="Silver Arrows"></p>
<p>However, this happened as a wave of distributed innovation. There was no central
planning and no vision — it all happened organically. Which explains
why a lot of our day-to-day development tools overlap, compete, and require a ton
of compatibility code just to make them work with each other.</p>
<p>Let&#39;s take an example. Say you&#39;re a JavaScript developer and you use the latest and
greatest tools. You write your code in ES2017. But before you ship it to
your users you use a compiler like Babel which has to parse your code to compile
it to ES5. And you also want to bundle your code so you use a bundler like
Webpack which parses your ES5 code, collect the require/import statements, and
bundles your code. Finally, you also use a minifer like Uglify which has to also
parse and then minify your code.</p>
<p><img src="/public/images/js_compile.jpeg" alt="compiling JavaScript"></p>
<p>You may have noticed that there is only 3 parse steps in this pipeline, that&#39;s
because I ran out of slide space. The browser still needs to parse the code
before it executes it.</p>
<p><img src="/public/images/js_compile2.jpeg" alt="compiling JavaScript 2"></p>
<p>Ok, so what? Well, there is a good chance you&#39;re reading this article to kill time
while Webpack is recompiling. <em>Everything is slow</em>. There is also a
question of how many parsers, as a community, do we have to write and
maintain. Furthermore, there is lot of information loss as we go
down the pipeline — you might&#39;ve had Flow type annotations but those will not
be accessible for the minifier to emit optimized code because they&#39;re compiled
away at an earlier step.</p>
<p>(This is only one branch of the development pipeline, there is also the
IDE/static analysis and code generation that contains similar duplication of
work and incompatibilities).</p>
<p>Roughly speaking, we separate our tools by development life-cycle stage:
authoring, executing, testing, building, and deployment. Which limits how much
sharing of information and work can happen between tools.</p>
<p><img src="/public/images/so_what.jpeg" alt="so what"></p>
<p>Ok, then what if we imagined we live in a different world where we&#39;ve taken a more
<a href="https://repl.it/site/blog/holistic">holistic</a> approach to development
environments where we layer tools on top of each other. My IDE knows where and
how my code executes and can show me inline information about function calls,
error rates, and type information — heck, why won&#39;t production crashes translate
into local development breakpoints? What if my repo on Github could pull from the
same code intelligence service and have a click-to-symbol feature. Etc.</p>
<p><img src="/public/images/what_if.jpeg" alt="what if"></p>
<p>Alan Kay tells us that computing is &quot;pop culture&quot; because we have &quot;disdain for
history&quot;. Well, I&#39;d like to do better. So in looking at this problem I decided
to construct a historical narrative to help us understand how we got here.</p>
<p><img src="/public/images/poop_culture.jpeg" alt="poop culture"></p>
<h2 id="worse-is-better">Worse Is Better</h2>
<p><img src="/public/images/worse_is_better.jpeg" alt="worse is better"></p>
<p>In March 1990 Gaberial stood in front of crowd of Lisp developers and told them
that <a href="https://www.dreamsongs.com/RiseOfWorseIsBetter.html">&quot;Worse is Better&quot;</a>. The Lisp community&#39;s who&#39;s who were in the audience and
they weren&#39;t very happy with the talk. After the talk, Gerry Sussman was the
first to stand up and claim nonsense. Followed by Carl Hewitt, and there was
Gaberial defending a position that, had the Lisp community understood, maybe the
world of software engineering today would&#39;ve been very different.</p>
<p>See the Lisp community practiced the Right Thing software philosophy which was
also know as &quot;The MIT Approach&quot; and they were also known as &quot;LISP Hackers&quot;.</p>
<p><img src="/public/images/lisp.jpeg" alt="lisp"></p>
<p>The larger research community that the Lisp community was part of was operating
under a vision of computing that Alan Kay recently mentioned in a <a href="https://www.quora.com/What-made-Xerox-PARC-special-Who-else-today-is-like-them">Quora answer</a>:
<em>“The destiny of computers is to become interactive intellectual amplifiers for
everyone in the world pervasively networked worldwide”</em>.</p>
<p><img src="/public/images/vision.jpeg" alt="vision"></p>
<p>They were building amazing technology. Take for example Interlisp, a
bootstrapped end-to-end Lisp programming environment that featured a structure
editor (picture editing AST nodes instead of text), a REPL (with undo, which
right now is coming back as &quot;time-traveling debugger&quot;) and among many other things
automatic error correction.</p>
<p><img src="/public/images/interlisp.jpeg" alt="interlisp"></p>
<p>Meanwhile in New Jersey the &quot;Worse is Better&quot; folks, also known as &quot;New Jersey
Style&quot;, also known as &quot;C hackers&quot; were hacking on the C programming language and
the Unix operating system. They had a much more pragmatic approach than the MIT
approach — they valued, above anything else, a simplicity of
implementation. Almost exactly the opposite of what the MIT folks valued, which
is simplicity of interface, completeness, and correctness.</p>
<p>(I like to imagine a late-night stoner-like conversation between Dennis Ritchie
and Ken Thompson:</p>
<p><em>&quot;Dude, what if, like, everything was made of files?&quot;</em></p>
<p><em>&quot;Everything?&quot;</em></p>
<p><em>&quot;Yeah, like eeverrryyything&quot;</em></p>
<p><em>&quot;Whoaa&quot;</em>)</p>
<p><img src="/public/images/meanwhile_in_nj.jpeg" alt="meanwhile in new jersey"></p>
<p>Back to Richard Gabriel. After he was lambasted by everyone at the conference he
went home, hid his essay, and vowed never to talk about it
again. See he knew that in the wrong hands Worse is Better — which although the
New Jersey folks were practicing they weren&#39;t preaching — could do a lot
of damage.</p>
<p><img src="/public/images/never_worse_is_better.jpeg" alt="never worse is better"></p>
<p>A couple of years later Richard hired a young hacker by the name of <a href="https://www.jwz.org/">Jamie Zawinski</a>
(later of Netscape fame — and can be found running a nightclub somewhere in
the SoMa district of SF). Like most hackers Jamie believed that information
should be free so when he found the Worse is Better paper he decided, without
asking Richard, to <a href="https://www.dreamsongs.com/WorseIsBetter.html">send it</a> to
all his friend. It then spread like wildfire across the industry.</p>
<p><img src="/public/images/jwz.jpeg" alt="jwz"></p>
<p>What was supposed to be a wake up call became a self-fulfilling
prophecy. Richard talks about how &quot;Large companies (with 3-letter names)&quot;
(hint: IBM) used the Worse is Better paper a reference for training employees on
how to design software.</p>
<p><img src="/public/images/prophecy.jpeg" alt="self-full-filing prophecy"></p>
<p>Later in his career Richard — realizing that he was responsible for the final nail
in the coffin that killed the Right Thing approach to software development — began
writing against Worse is Better <a href="https://www.dreamsongs.com/Files/worse-is-worse.pdf">under a pseudonym</a>. Legend has it that he
became so confused about this subject that he was once invited to talk about
it and both argued for and against Worse is Better.</p>
<p><img src="/public/images/richard_pseudonym.jpeg" alt="Richard arguing against worse is better"></p>
<p>Now that I understand our place in history I can&#39;t help but wonder what would&#39;ve
happened if the Right Thing philosophy had won out. If
our development environment resembled something like Interlisp instead of
Unix. I think maybe since the main feature of Worse is Better is that — in
the words of Richard — &quot;it spreads like virus&quot; it had been better for computing to
adopt this approach to achieve scale. But now what? I think we should be more
ambitious and bring back the Right Thing.</p>
<p>(<em>In the talk which this is based on I talk a bit about what I&#39;m doing about the
problem. I&#39;ve written briefly about this elsewhere: <a href="https://repl.it/site/blog/holistic">&quot;Building Towards a Holistic Development Service&quot;</a></em>)</p>
]]></content:encoded>
            <author>amjad.masad@gmail.com (Amjad Masad)</author>
            <enclosure url="https://amasad.me/public/images/interlisp.jpeg">
            </enclosure>
        </item>
        <item>
            <title><![CDATA[Fake Minimalism]]></title>
            <pubDate>Thu, 12 Jan 2017 00:00:00 GMT</pubDate>
            <description><![CDATA[ It's now fashionable to call yourself a "minimalist", but is that merely about not having things? I remember going to school everyday carrying nothing at all, no bag, no books, no pen, nothing -- I w...]]></description>
            <content:encoded><![CDATA[<p>It&#39;s now fashionable to call yourself a &quot;minimalist&quot;, but is that merely about not having things? I remember going to school everyday carrying nothing at all, no bag, no books, no pen, nothing -- I was a slacker. If I needed a
pen, say for a pop quiz, I had to borrow one quickly. In other words, I depended
on my classmates to provide the pen. Is this really minimalism? Yes, I didn&#39;t need the material possession of a pen, but I had to depend on others to provide the pen.</p>
<p>In Silicon Valley, where your company feeds you, washes your clothes, and supply your
social life, are you a minimalist for not having a kitchen, a washer, or friends
outside of work? Defined this way, a baby is the ultimate minimalist, after all
it has zero possessions and relies on the mother for everything.</p>
<p>I think self-sufficiency needs to be taken into account when evaluating
minimalism -- even if it&#39;s at the cost of having more material possessions. For
instance, buying a hair clipper and spending a bit of time learning how to
cut my own hair is definitely more minimal than relying on a barber that I have
to schedule with, pay to, and go to (that can get sick, go on vacation, or
move away).</p>
<p>A similar thing happens in software all the time -- is it more minimal:</p>
<ul>
<li>to use a service than it is implement your own?</li>
<li>to take on a software package dependency than it is to write your own library?</li>
<li>to have users always augment your app with some other app for a missing
feature than it is to add it?</li>
</ul>
<p>A Fake Minimalist will go with the former for every case.</p>
<p>In his <a href="https://youtu.be/oyLBGkS5ICk?t=23m">&quot;Spec-ulation&quot; talk</a>, Rich
Hickey brought this point home by defining software growth as (my emphasis):</p>
<ul>
<li>Accretion: to provide more functionality.</li>
<li><strong>Relaxation: to require less (dependencies, inputs, etc).</strong></li>
<li>Fixation: to fix bugs.</li>
</ul>
]]></content:encoded>
            <author>amjad.masad@gmail.com (Amjad Masad)</author>
        </item>
        <item>
            <title><![CDATA[2016]]></title>
            <pubDate>Sun, 08 Jan 2017 00:00:00 GMT</pubDate>
            <description><![CDATA[ I'm typically forward looking and barely take time to reflect (not to say those two things are mutually exclusive). However, last year was a especially unique and crazy, so in honor of that (and the ...]]></description>
            <content:encoded><![CDATA[<p>I&#39;m typically forward looking and barely take time to reflect (not to say
those two things are mutually exclusive). However, last year was a especially unique and
crazy, so in honor of that (and the new blog design) I decided to sit down,
reflect, and write something.</p>
<p>This will be roughly chronological going through the big events that took place last
year, and will conclude with some books, lectures, and ideas that had a big
impact on my thinking and worldview.</p>
<h2 id="leaving-facebook">Leaving Facebook</h2>
<p>At the beginning of the year it seemed like I finally arrived at job
happiness. In 2015 I helped start the JS Infra team at Facebook. The motivation
for building this team came from my experience building the React Native Packager where I noticed that the
infrastructure that we&#39;re basing our development toolkit on was poorly
maintained, bug-ridden and in some cases poorly designed with no hope without a
full rewrite (or replacement).</p>
<p>So we assembled an amazing team of engineers to build out the basic building blocks that
would power Facebook&#39;s JavaScript development (and hopefully the JS community at large).</p>
<p><img src="/public/images/js_infra.jpg" />
<em>JS Infra sailing off-site. Not in the photo: Christoph Pojer (which was taking the photos). And our
manager Tom Occhino</em></p>
<p>Although the JS infra team was deeply technical and in some cases working on
problems a few layers removed from the developer experience, we always thought
it&#39;s best to start from the user experience and work our way backwards. For
instance, I remember talking to
someone from the Parse team who told me about a metric they used to make sure their
tools are easy to get started with: TTH, time till hello world. So when the time came to think about how people would get started with React
Native, it was obvious that the CLI needs to be robust enough to guide the user
all the way through to see something on the screen within 5 minutes of installation!</p>
<pre><code class="lang-bash">react-<span class="hljs-keyword">native</span> <span class="hljs-keyword">init</span> AwesomeProject
cd AwesomeProject
react-<span class="hljs-keyword">native</span> run
</code></pre>
<p>Although our team wasn&#39;t perfect, we had immediate impact starting with the
first half in our existence. We worked on and released Babel 6, which took Babel
from being merely a transpiler to being a platform and a compiler toolkit. We switched over
Facebook&#39;s entire JS infrastructure to use it. And not only used it for transpiling
it was now being used by teams throughout the company for things like i18n,
accessibility, optimization and so much more! We fixed Jest and it became a few order
of magnitudes faster. We continued improving on the React Native packager which
became a central piece of infrastructure at the company (both as a
development tool and as a build system).</p>
<p>Unfortunately, not everyone at the company believed that our team&#39;s existence is
justified. There was a big push to work on performance (which I
thought was justified since the website was very slow). So there was a lot of pressure on
us to dump everything that we&#39;re working on and focus a 100% on performance.</p>
<p>I didn&#39;t agree that
what we&#39;re doing and the performance goal weren&#39;t aligned. But in the
end I lost the office politics game and our team was all but
dismantled. Luckily, I had a great manager, and great support from many other
people at the company. So I was given a chance to find something I could
be as passionate about. But to be honest, my passion had already drifted
towards an old but growing side project of mine.</p>
<p>(A new and improved version of the team has now reassembled and are building
amazing things for the JS community -- like the Yarn package manager!)</p>
<h2 id="starting-repl-it-the-company-">Starting Repl.it (the company)</h2>
<p>In 2015 Haya Odeh and I planned to give an old side project of
ours a face-lift -- mostly just for fun. We knew that some people were using
<a href="https://repl.it">Repl.it</a> but when we looked, we where surprised to see that there are 10s of
thousands of people using it a month. We started researching, visiting our
users, and doing surveys. We found that our biggest impact was on physical
classrooms across the country and the world. (Which was not that big of a
surprise).</p>
<p><img src="/public/images/replit_school.jpg" />
<em>Haya talking to students using Repl.it at the Mountain View High school</em></p>
<p><a href="https://repl.it">Repl.it</a> was
always at least partly about education. Back in school, I was displeased with the fact that every
class I went to
had to spend hours installing software. And I watched the instructor struggle to
get everyone&#39;s compilers and editors setup (with matching versions). I started
dreaming up a site where you open a new tab and start coding. And in 2011 that&#39;s
what we built and not only did it help with that, we open-sourced the underlying
execution engine (built with emscripten) which went to on power many
learn-to-code websites (most famously, Codecademy, which I joined as the #1
employee).</p>
<p>One thing lead to another, and my brother Faris joined us in working on the
project and we ended up not only redesigning the website, but we added user
accounts, built a <a href="https://repl.it/api">cloud-based code execution engine</a> and
many smaller features. We also started planning a totally new product on top of
our core offering -- a classroom product that automates many of the tedious tasks
we noticed a teacher has to do to manage their classroom. Things like submitting
homework, giving feedback on homework, and tracking student progress.</p>
<p>We incorporated in May, 2016 with the mission to make programming more
accessible. We&#39;re building powerful yet simple coding interfaces for programmers
and students. And we&#39;re building a platform for teachers that want to bring
programming to their classroom or reach a wider audience online.</p>
<h3 id="repl-it-classroom">Repl.it classroom</h3>
<p>We rushed to build our first major product as a company. After tons of
research and a tight feedback loop with a handful of teachers it was ready for
the release just before the fall school season started. We launched in August and much
to our surprise that put us on an exponential growth curve. Professors at universities
like CMU signed up and used us to teach &quot;Math Background for Machine
Learning&quot;, followed by MIT, Cornell and many others. Bootcamps like Hack Reactor and App Academy used us for introductory
courses. And high-schools across the US, UK, Japan, and elsewhere in the world
started signing up.</p>
<p><img src="https://repl.it/public/images/studentenvironment.png" />
<em>The student environment</em></p>
<h3 id="partners">Partners</h3>
<p>We&#39;re so lucky to be in this part of the world -- Silicon Valley is a place where immigrants can
come in and build companies. We&#39;re double lucky to have found the support and
mentorship of amazing people. Repl.it is now backed by Bloomberg Beta and Reach
capital and I could&#39;ve never imagined that the founder/investor relationship
could be this good. We&#39;re still starting out and the journey is only 0.0001%
complete (Facebook likes to say it&#39;s 1% complete), but whatever modest success
we achieved we couldn&#39;t have done it without the support and mentorship of Roy
Bahat, Wayee Chu, Christina Cacioppo, Chris Mather, and Ly Nguyen.</p>
<h3 id="repl-it-in-2017">Repl.it in 2017</h3>
<p>We spent the last quarter of 2016 focused on the core REPL product -- adding
more power yet maintaining the simplicity. We added support for <a href="https://repl.it/site/blog/package-search">third-party
libraries</a>, implemented a
<a href="https://repl.it/site/blog/python-debugger">debugger</a>, and live file updates.
You can see more on our <a href="https://repl.it/blog">blog</a>.</p>
<p><img src="http://i.imgur.com/aQ6S00P.gif" />
<em>Live file updates</em></p>
<p><img src="https://i.imgur.com/oerWaQR.gif" />
<em>Debugging</em></p>
<p>We also grew the team and hired our first employee. This month, we&#39;ll be moving
to our first private office and we&#39;re hoping to add more engineers to the team
soon. We have a lot of interesting technical challenges, and we&#39;d like to think
we&#39;re working on an important mission, if that&#39;s interesting to you then
consider joining us :)</p>
<p>This year we&#39;re going to continue being heads-down focused on product and
technology. We have a lot of interesting features in the pipeline. But most
importantly we want to find ways to have our teachers, students, and
engineers collaborate with each other and build an awesome community.</p>
<h2 id="thoughts-books-etc">Thoughts, books, etc</h2>
<h4 id="coming-to-terms-with-physicalism">Coming to terms with Physicalism</h4>
<p>You don&#39;t notice how much outdated belief you have in your head until you
sit down and examine them. In a recent talk, <a href="https://www.youtube.com/watch?v=fhOHn9TClXY&amp;feature=youtu.be&amp;t=1h1m6s">Alan Kay
describes</a>
how every 3-5 years he sits down and writes down all his beliefs in an effort to
update them.</p>
<p>This year I did this for my worldview and my philosophy on the
nature of the universe. Physicalism is the thesis that everything is
physical. That means -- among many other things -- that your mind/soul is a product of the physical processes
in your body, and it obeys the laws of physics just like an apple falling from a
tree. The implications here are big and many. It also could be scary, but luckily I was aided
by a few books that I recommend to anyone who wants to come to terms with this.</p>
<h4 id="rationality-from-ai-to-zombies"><a href="https://intelligence.org/rationality-ai-zombies/">Rationality: From AI to Zombies</a></h4>
<p>To build an AI you need to understand and describe how the human mind works (and
how it often doesn&#39;t). This book helped me in a few ways:</p>
<ul>
<li>I now understand pervasiveness of cognitive biases and fallacies. In the words
of Richard Feynman: &quot;You are the easiest person to fool&quot;.</li>
<li>Using a mix fables and science the author gently guides you from the default dualist
belief (mind is separate from the body/world) to a purely physical world.</li>
<li>Presents different ways to think about some of the seeming absurdities of Physicalism (for
example, are we all just cogs in the unwinding clock that is the universe?).</li>
</ul>
<p>The book has all sorts of tips and tricks to help you face up to the truth. One
of my favorites is the <a href="https://wiki.lesswrong.com/wiki/Litany_of_Gendlin">&quot;Litany of
Gendlin&quot;</a>:</p>
<blockquote>
<p>What is true is already so.<br/>
Owning up to it doesn&#39;t make it worse.<br/>
Not being open about it doesn&#39;t make it go away.<br/>
And because it&#39;s true, it is what is there to be interacted with.<br/>
Anything untrue isn&#39;t there to be lived.<br/>
People can stand what is true,<br/>
for they are already enduring it.</p>
</blockquote>
<h4 id="the-beginning-of-infinity-explanations-that-transform-the-world"><a href="https://www.amazon.com/Beginning-Infinity-Explanations-Transform-World/dp/0143121359">The Beginning of Infinity: Explanations That Transform the World</a></h4>
<p>This book layed out the basis for a hopeful and optimistic Physicalist
worldview. It gives people (or universal explainers in general, as
the book calls them) a more privilege place in the universe. Yes, we are
&quot;chemical scum&quot; that evolved via Darwinian selection but our reach can be
infinite. And our journey has just begun towards the infinite creation of knowledge.</p>
<h4 id="personal-identity">Personal Identity</h4>
<p>The concept of &quot;self&quot; seems to be a hack. Evolution gave us this abstraction
because it seems to simplify a lot of things -- most importantly,
self-preservation (so we can take care of ourselves until we procreate). This
idea started forming in my head in 2015 after reading <a href="https://www.amazon.com/Society-Mind-Marvin-Minsky/dp/0671657135">Marvin
Minsky&#39;s Society of
Mind</a>, which
plausibly breaks down the mind into modules and presents it as if it&#39;s a big
piece of software.</p>
<p>Consider how split brain patients seem to have two sides of their brains
behave somewhat autonomously (as if it&#39;s a different person). In this
<a href="https://youtu.be/aCv4K5aStdU?t=1m35s">video</a> the patient&#39;s right hemisphere is
shown a word (via his left eye) but he couldn&#39;t say what it was. However, when
he closed his eyes and started drawing he was able to draw a pan (which is the
word that he saw).</p>
<p>This is just scratching the surface, earlier this year I started reading <a href="https://www.amazon.com/Reasons-Persons-Derek-Parfit/dp/019824908X">Reasons
and Persons</a>
by the late Derek Parfit (died a few days ago). It includes all sorts of
thought experiments that all but destroys the concept of self. I couldn&#39;t
finish the book because it was too hard and jargony. However, luckily, I found
a course on YouTube titled <a href="https://www.youtube.com/watch?v=p2J7wSuFRl8&amp;list=PLEA18FAF1AD9047B0">Death</a> that draws heavily from Parfit&#39;s work on
personal identity. And this completely shattered how I thought about my self and
my place in the world.</p>
<p><img src="http://ctl.yale.edu/sites/default/files/kagan.jpg" /></p>
<p>I&#39;m now more accepting of the fact that I and everyone I know and love
will die in the not very distant future. I feel more connected to other
people. And finally understand what it means to have an impact in the
world (improve lives and reduce suffering).</p>
<p>(For a quick primer on the subject I recommend Wait But Why&#39;s <a href="http://waitbutwhy.com/2014/12/what-makes-you-you.html">&quot;What Makes You
You?&quot;</a> essay).</p>
<p>Thanks for reading.</p>
]]></content:encoded>
            <author>amjad.masad@gmail.com (Amjad Masad)</author>
        </item>
        <item>
            <title><![CDATA[Kierkegaard and Entrepreneurship]]></title>
            <pubDate>Thu, 14 Apr 2016 00:00:00 GMT</pubDate>
            <description><![CDATA[Earlier this year I spent a lot of time thinking about what "impact" means to me. In the tech world, we use it to say that our work matters and that we're "making a dent in the universe". But it feels...]]></description>
            <content:encoded><![CDATA[<p>Earlier this year I spent a lot of time thinking about what &quot;impact&quot; means to
me. In the tech world, we use it to say that our work matters and that we&#39;re
&quot;making a dent in the universe&quot;. But it feels empty most of the time. I came to
the conclusion that &quot;impact&quot; has no meaning to me when I&#39;m easily
replaceable. No matter how many people&#39;s lives I&#39;m touching with software that
I&#39;ve written, if I&#39;m not bringing something unique -- a part of myself -- into
my work then I&#39;m not doing something worth doing.</p>
<p>Last month, on the <a href="https://www.youtube.com/watch?v=1yPbakzvrx0">Philosophize This
podcast</a>, I heard about
Kierkegaard&#39;s work on despair and found it to be a weirdly good articulation of
my thoughts on work fulfillment and progress. He was a 19th century Danish philosopher
and wrote primarily on psychology and the human condition. Although he viewed
most things through the lens of theology, it&#39;s common -- and works pretty well
-- to have a secular reading of his work.</p>
<p>He viewed the self as having two opposing aspects. One that he called the
infinite and the other is the finite. He described the relationship between them
as dialectical -- which means that one cannot exist without the other and that
there is constant tension between them. Furthermore, there exists a &quot;synthesis&quot;,
a point which we can balance these contradicting forces.</p>
<h2 id="the-infinite-and-finite">The infinite and finite</h2>
<p>The finite aspect of the self deals with worldly facts about the person. It is
the condition in which one exists. Your name, sex, race, and even things that
are more general like the social, political, and cultural environment that you
find yourself in. The finite is concerned with necessity as opposed to
possibilities -- things that are largely predetermined.</p>
<p>The infinite is the aspect of the self that deals with abstractions, different
meanings, and possibilities. And imagination is its primary device. The
infinite is concerned with what the self can become as opposed to its current
state. It opens up opportunities to free oneself from the rigidity of finite
existence.</p>
<p>If someone lacked either aspects of themselves, Kierkegaard thought they&#39;d be in
a state of despair -- they can lose themselves in the infinite or in the finite.</p>
<h2 id="the-finite-is-the-default">The finite is the default</h2>
<p>There is generally a set path in life for people to follow. Most choices are
made for us, and someone can exist purely within the tracks that were
manufactured for them by their parents, culture, and society. After we graduate
and become adults we go to work and get plugged into the place that is deemed
most fit for us and contribute our small part as cogs in the machine.</p>
<blockquote>
<p>Just by losing himself this way, such a man has gained an increasing capacity
for going along superbly in business and social life, indeed, for making a
great success in the world. Here there is no delay, no difficulty with his self
and its infinitizing; he is as smooth as a rolling stone, as courant [passable]
as a circulating coin. He is so far from being regarded as a person in despair
that he is just what a human being is supposed to be.</p>
</blockquote>
<p>Bob is an engineer because his father was an engineer. He uses vim because
everyone at work uses vim. He takes the designs passed to him by his product
manager and implements them 100% according to spec. He never questions
anything. He is moved by his managers from team to team without any
objections. When asked why he&#39;s doing what he&#39;s doing, he parrots what his
manager told him about the importance of the mission and how he fits in. He is
as passable as a coin.</p>
<blockquote>
<p>by getting engaged in all sorts of worldly affairs, by becoming wise about how
things go in this world, such a man forgets himself, forgets what his name is
(in the divine understanding of it), does not dare to believe in himself, finds
it too venturesome a thing to be himself, far easier and safer to be like the
others, to become an imitation, a number, a cipher in the crowd.</p>
</blockquote>
<p>Bob is so easy to replace. He provides nothing to his team, work, society, or
family that is unique to himself. He&#39;d rather lose himself in the crowd, become
indistinguishable, than be himself.</p>
<blockquote>
<p>it is dangerous to venture. And why? Because one may lose. But not to venture
is shrewd. And yet, by not venturing, it is so dreadfully easy to lose that
which it would be difficult to lose in even the most venturesome venture, and
in any case never so easily, so completely as if it were nothing ...one’s self.</p>
</blockquote>
<p>Bob should know that he stands to lose more by accepting the default. He risks
losing himself by taking the seemingly safe and secure choice. Let alone dream,
imagine, or take the time to figure out what he really cares about in this
world.</p>
<h2 id="lost-in-the-infinite">Lost in the infinite</h2>
<p>Engaging in the infinite aspect of the self is important to balance out the
finite. To come up with new ideas, new understanding of the world, and new
meaning. In other words, to become something more. But unless this process is
grounded in reality (the finite), the self may risk becoming too abstract,
fantastic, unreal.</p>
<p>For example, if Bob loves humanity so much it makes him weep, it&#39;s just his boss
he cannot stand. He has been carried away into the abstract, the infinite, and
have lost his relation to the finite, the concrete. He holds an abstract and
<a href="https://wiki.lesswrong.com/wiki/Free-floating_belief">free-floating belief</a>
that&#39;s not influencing his behavior.</p>
<p>Similarly a person may get caught up in abstract knowledge that never makes its
way back to the finite world. For example, Bob likes to learn about Machine
Learning, he accumulates a whole lot of knowledge on the subject but never gets
a chance to apply it at his job. Bob has lost himself in pursuing this knowledge
because he is not able to benefit himself or the world from it.</p>
<p>Finally, and more relevant to our discussion, is being lost in &quot;willing&quot; (or
wishing). For example, Bob wishes the world to move to renewable energy. But he
never takes an action towards that end. This goal is so out of his control that
there seems to be nothing he can do about it. He never grounds his imagination
in the finite. He doesn&#39;t take the time to come up with the smallest possible
task that can be a step towards achieving his desired state.</p>
<blockquote>
<p>the will does not constantly become concrete in the same degree that it is
abstract, in such a way that the more it is infinitized in purpose and
resolution, the more present and contemporaneous with itself does it become in
the small part of the task which can be realized at once, so that in being
infinitized it returns in the strictest sense to its self, so that what is
farthest from itself (when it is most infinitized in purpose and resolution) is
in the same instant nearest to itself in accomplishing the infinitely small
part of the task which can be done even today, even at this hour, even at this
instant.</p>
</blockquote>
<h2 id="entrepreneurship">Entrepreneurship</h2>
<p>I view entrepreneurship as means of reconciling the infinite and finite. You
venture into your imagination, gather knowledge, and dream about a better
world. But you have to bring some of that back to earth. You take a step -- no
matter how small -- towards your imagined world in the real world.</p>
<p>This is not a one time thing, it&#39;s a recursive process. If your imagined
possibilities became real then that&#39;s your new &quot;finite&quot;. The process restarts
and that&#39;s how we make progress.</p>
<p>This notion of progress comes from <a href="https://en.wikipedia.org/wiki/Dialectic#Hegelian_dialectic">Hegelian
dialectic</a>. When
traversing dialectical opposites like the infinite and finite, and are finally
able to reconcile the conflict and arrive at common truths. This becomes our new
reality and the process restarts.</p>
<p>I see this as the perfect framework for the work we do in technology. There is
always a tension between what is and what could be. There are people and
organizations who are stuck in the status quo (the finite). On the other hand,
there are folks who are stuck in the what could be without any actionability
(the infinite).</p>
<p>Taking a step into the infinite could be hard, but the hardest thing of all is
bringing something back to the finite. The real art is coming up with the
smallest possible task that can be done here and now.</p>
<p>Take Elon Musk for example, like Bob, he wants the world to move to renewable
energy but that&#39;s such a big and daunting task that seems unapproachable. Elon
could&#39;ve been lost in the infinite. Instead he took a step towards doing
something within his reach. He started an electric super-car company. It&#39;s
counter-intuitive how this is relevant as outlined in his <a href="https://www.teslamotors.com/blog/secret-tesla-motors-master-plan-just-between-you-and-me">master
plan</a>
in 2006:</p>
<blockquote>
<p>The strategy of Tesla is to enter at the high end of the market, where
customers are prepared to pay a premium, and then drive down market as fast as
possible to higher unit volume and lower prices with each successive model.</p>
</blockquote>
<p>Ten years later, Tesla is shipping the first mass-market electric car and
innovating in battery technology. Making real progress towards a renewable
energy world.</p>
<p>Not everyone can be Elon Musk, but we all can be entrepreneurial in our own
sense. I think the most important thing is to always make progress. Don&#39;t get
stuck in the weeds for too long. Imagine a better world, and take a small step
towards it.</p>
]]></content:encoded>
            <author>amjad.masad@gmail.com (Amjad Masad)</author>
        </item>
        <item>
            <title><![CDATA[What is Perfectionism and How to Cure It]]></title>
            <pubDate>Sun, 13 Mar 2016 00:00:00 GMT</pubDate>
            <description><![CDATA[ > My problem is that I'm a perfectionist > -- Everbody  As I finished writing the title for this post I thought about quitting. I didn't think it was good and told myself that this is off to a bad st...]]></description>
            <content:encoded><![CDATA[<blockquote>
<p>My problem is that I&#39;m a perfectionist
-- Everbody</p>
</blockquote>
<p>As I finished writing the title for this post I thought about quitting. I didn&#39;t
think it was good and told myself that this is off to a bad start and it&#39;ll only
get worse as I write more words. There is always an easy fallback to
get out of doing hard work without feeling bad about it: &quot;I&#39;m a perfectionist,
and I can&#39;t possibly achieve perfection in this project so I&#39;m going to quit altogether&quot;.</p>
<p>What was really going on here is that I realized that it&#39;s going to be harder
than what I imagined it would be, and I just didn&#39;t want to do the work. Just
being lazy. Laziness is a simplification here and in this post I&#39;ll go over all the
layers that I&#39;ve been able to debug in myself.</p>
<h3 id="false-dichotomies">False dichotomies</h3>
<p>I often notice that before I throw my hands in the air and claim perfectionism I
present myself with a dichotomy: &quot;It&#39;s either that I finish this work and hit all
my goals or it&#39;s not valuable to anyone&quot;. Here are some examples:</p>
<ul>
<li>&quot;I don&#39;t think it&#39;s worth going to the gym today because I know I don&#39;t have
the time to go everyday and get six packs&quot;</li>
<li>&quot;I need to revamp my blog before I write my blog post and I don&#39;t have the
time to do all that now&quot;</li>
</ul>
<p>The truth is that most things are still valuable even in there imperfect or
unfinished form. For example, it&#39;s hard to argue with the effectiveness of the
popular Minimum Viable Product approach to product development. You&#39;re able to
deliver value to people and at the same time test and iterate on your ideas.</p>
<p>Back to our examples, going to the gym at any time no matter what the situation is will be
a categorically positive thing to do. And writing a blog post doesn&#39;t strictly
depend on your blog&#39;s design (I almost fell for this one the other day).</p>
<h3 id="decision-fatigue">Decision fatigue</h3>
<p>Another thing that I&#39;ve detected in myself that would make me fallback on the
&quot;I&#39;m a perfectionist&quot; excuse is <a href="https://en.wikipedia.org/wiki/Decision_fatigue">decision
fatigue</a>. You can get tired from
just making decisions if you had to do so many of them while working on
something.</p>
<p>Say for example you want to tidy up your apartment. Since this is such a general goal, you&#39;ll be faced
with so many questions along the way: &quot;Should I fold my clothes like I always do
or is it time reorganize my closet? Should I throw out the books I&#39;m not using?
Should I maybe give them away?&quot; and so on. Very soon you&#39;ll be tired just from
answering these questions without even doing much work. Then you&#39;ll see the
nice and cozy excuse waiting for you: &quot;I&#39;m such a perfectionist I can&#39;t even tidy up
my room!&quot;.</p>
<h3 id="embarrassment">Embarrassment</h3>
<p>Putting yourself and your work in the public requires a great deal of
courage. For probably some evolutionary survival reasons we tend to think about
all the things that could go wrong. One of the strongest negative emotions that
I get when I&#39;m not certain about the quality of my work is the feeling of being
embarrassed by it. That people much smarter than me will look at it and
laugh about how bad it is. That&#39;s almost never the case. I&#39;ve written some
really silly posts and code and it rarely gets ridiculed. Even when it does happen,
it&#39;s usually by people that I don&#39;t necessarily respect or look up to (see my
post about on the <a href="http://amasad.me/2016/01/13/the-stoic-of-open-source/">Stoic of Open
Source</a> for an example of
this). That is not to
say that everything I do is perfect, in fact, I get really awesome constructive
feedback every time I release something.</p>
<p>Another tactic for avoiding embarrassment is not to
over-promise. I&#39;d go as far as to say you should not talk about your
ideas before verifying that they work (see my post about <a href="http://amasad.me/2016/03/09/john-carmack-on-idea-generation/">idea
generation</a>). Which
reminds me of what <a href="https://twitter.com/tomocchino">Tom</a> my manager (who manages
projects like React and Flow at Facebook) likes to say: &quot;under-promise, over-deliver&quot;.</p>
<h3 id="confidence">Confidence</h3>
<p>If you aspire to do quality work you need to be able to trust in your abilities.
Or at least that you would try really hard. Going back to the meta-example of writing this post. If I
were confident of my abilities to overcome any hardship that started with the
title, I would keep going while knowing that I will rewrite this as many time as
it takes to get it to good enough state.</p>
<p>So I would need to be confident of my ability to get close to the goal, and in
my ability to persevere and work hard enough to get there.</p>
<h3 id="curing-perfectionism">Curing perfectionism</h3>
<p>Recognizing these patterns in our behavior is a good first step in getting over
them. I had a lot of success with -- what I later discovered to be -- cognitive
behavioral therapy. <a href="http://cbtsanfrancisco.com/cbt-is-for-hackers/">This is a good introduction</a> to the subject but we&#39;re
mainly interested in the following methods:</p>
<ul>
<li>Forced Activity</li>
<li>Exposure</li>
</ul>
<p>Forced Activity is when you recognize a vicious cycle in your behavior and force
yourself out of it. It&#39;s forced because you need to swim against the
current in order to break out. For example, if you noticed that you always start
projects but quit and claim perfectionism, then try to start the smallest project
possible that is actually perfectible and finish it. If you have too many unread
books and you stopped reading because you can&#39;t possibly finish all the books
then go throw them out (or delete everything on your kindle). Even if the action is a
bit radical, do it to get you out of the cycle.</p>
<p>Exposure is when you tackle psychological pain by leaning into it. Start small
with something you fear and do more and more. If, for example, you&#39;re afraid of
publishing code then start by publishing a gist of a program that does something useful
and share it. Then slowly work your way up to sharing a library and finally to
contributing to large open source projects.</p>
<p>Up until last year, I had a crippling  fear of public speaking and this method worked really well for
me. Although I&#39;ve spoken a few times before, every time I spoke the fear was
worse than the one before. However, after committing
to the Exposure method I started small by
<a href="https://twitter.com/brooklyn_js/status/436669188103344128">speaking</a> at a
friendly and welcoming meetup in NYC called BrooklynJS. And then worked my way
towards a larger conference and spoke at
<a href="https://www.youtube.com/watch?v=rcjUR4icvoQ">EmpireJS</a>. I then started really
leaning into it and even performed at a <a href="https://www.facebook.com/events/311252482399585">story telling
show</a>. And finally completely
improvised a couple of meetup talks. I&#39;m now almost fearless when it comes to public
speaking.</p>
<p>In conclusion I think that perfectionism is mostly a thin veil hiding a
multitude of insecurities, fears, and logical fallacies. And it&#39;s something we
need to face in order to reach self-actualization.</p>
<hr>
<p><em>Thanks to <a href="https://twitter.com/hayaodeh">Haya Odeh</a> for reviewing this post and
 providing feedback, examples, and refining many of the ideas mentioned here.</em></p>
]]></content:encoded>
            <author>amjad.masad@gmail.com (Amjad Masad)</author>
        </item>
        <item>
            <title><![CDATA[John Carmack on Idea Generation]]></title>
            <pubDate>Wed, 09 Mar 2016 00:00:00 GMT</pubDate>
            <description><![CDATA[ Last year at an internal talk at Facebook I was fortunate to see [John Carmack](https://en.wikipedia.org/wiki/John_Carmack) speak about his idea generation system. At first I was disappointed because...]]></description>
            <content:encoded><![CDATA[<p>Last year at an internal talk at Facebook I was fortunate to see <a href="https://en.wikipedia.org/wiki/John_Carmack">John
Carmack</a> speak about his idea generation system. At first I was disappointed
because I was expecting one of Carmack&#39;s famous technical talks where he spends hours talking
non-stop about programming languages, game development, large scale software
engineering and many other interesting technical topics.</p>
<p>Instead, he opened with talking about -- what is now a Silicon Valley cliche --
how ideas are overrated and execution is everything. Of course, cliches are
sometimes cliches because they&#39;re true. However, things took an interesting turn
when he mentioned the &quot;Antifragile&quot; concept.</p>
<h2 id="antifragile">Antifragile</h2>
<p>A phenomena discovered by Nicholas Nassim Talib that describes things that are
the opposite of fragile. We don&#39;t currently have a word to describe this in
English. You might think that words like &quot;robust&quot; or &quot;resilient&quot; come close
but actually those words describe systems that don&#39;t break under stress, but
what about things that benefits from stress?</p>
<p>To me, this was one of those questions that you realize is simple but
you&#39;re surprised that it hasn&#39;t entered your consciousness until this day.</p>
<p>Here is the description from the <a href="http://www.amazon.com/gp/product/B0083DJWGO/ref=dp-kindle-redirect?ie=UTF8&amp;btkr=1">Antifragile book</a>:</p>
<blockquote>
<p>Just as human bones get stronger when subjected to stress and tension, and rumors or riots intensify when someone tries to repress them, many things in life benefit from stress, disorder, volatility, and turmoil. What Taleb has identified and calls “antifragile” is that category of things that not only gain from chaos but need it in order to survive and flourish.</p>
</blockquote>
<p>After picking up this book and reading it, I was not only able to relate this
back to Carmack&#39;s idea system (more on this later) but saw the world in a slightly different
way. To give only one example, I see large open source software as antifragile. The
more stress people put the software under the better it becomes. The more
people use it in unanticipated ways and the more code path combinations are
exercised then the more bugs are found and fixed. In contrast, proprietary
software is usually used in controlled environments all the while building up
fragility for a major catastrophic event waiting to happen (see <a href="https://en.wikipedia.org/wiki/Black_swan_theory">Black Swan
Theory</a>).</p>
<h2 id="antifragile-idea-generation">Antifragile Idea Generation</h2>
<p>In programming and many other creative jobs you get many ideas in any single
day, but you can only implement a fraction of them. The fraction you haven&#39;t
implemented you might start obsessing about. Everyone has their pet ideas that
they go around discussing. The more time this idea spends in your head the less
critically you think of it. Now, when the time comes to
actually try implementing it, if it fails you&#39;re left discouraged, embarrassed and might even
quit the project you&#39;re working on.</p>
<p>This is obviously a fragile system. You start neutral, get a small high when you
first get the idea, and then it starts building up fragility while in your head. If and when it fails it&#39;s
catastrophic on your productivity.</p>
<p>So what does an antifragile system for generating ideas look like? First let&#39;s
lay out some criteria:</p>
<ol>
<li>Antifragile systems are -- by definition -- able get the upside but are not
affected by the downside. That means, we need to be able to get the initial idea
high and the motivation that comes with it.</li>
<li>Failure events must end up making our system stronger. Meaning when an idea
fails it needs to make the overall system better.</li>
</ol>
<p>Here is what Carmack thinks an antifragile system might look like:</p>
<ol>
<li>You are working on a problem and you get an idea and with it the initial idea
high</li>
<li>You should instantly try to defeat your idea -- think of all the ways it
could not work, test it out, put it under stress</li>
<li>If the idea survive the brutal scrutiny then it has legs for further
investigations or implementation</li>
<li>If the idea is implemented and it works then that&#39;s great</li>
<li>If the idea fails the scrutiny or implementation you can quickly move on to
the next idea without feeling the lows because you haven&#39;t
obsessed or talked about it i.e. it&#39;s not your pet idea.</li>
</ol>
<p>Carmack describes how this becomes like a game -- as soon as you get an idea you
try to defeat it. You&#39;ll be able to generate more ideas because you freed up
mental space. Furthermore, your existing ideas will
even be stronger because they survived heavy scrutiny.</p>
<h2 id="in-practice">In Practice</h2>
<p>I&#39;ve been using this at work and in my personal life for a few months now and I
recommend it to everyone. I end up prototyping a lot more and going through many
iterations of ideas. And that reminded me of my early days of programming. Because I
didn&#39;t know what was possible or not, I had to vet all my ideas by
coding them up. I went through multiple VB projects in any single day.</p>
<p>At work, we&#39;re now focused on JavaScript and web performance, and found this an
indispensable tool for this type of work. Optimization work (after crushing the
low-hanging fruit) is often counter-intuitive and many ideas that sound great in
theory end up tanking in practice. So to make progress we need to have a lot of
ideas and try many of them. And this gave me great framework to approach this with.</p>
]]></content:encoded>
            <author>amjad.masad@gmail.com (Amjad Masad)</author>
        </item>
        <item>
            <title><![CDATA[Caching and Promises]]></title>
            <pubDate>Sat, 05 Mar 2016 00:00:00 GMT</pubDate>
            <description><![CDATA[ It's fascinating to me how something that can be described so simply can also be tricky to implement. Caching is the idea of keeping around results of computations or outside-world-reads so it's easi...]]></description>
            <content:encoded><![CDATA[<p>It&#39;s fascinating to me how something that can be described so simply can also be
tricky to implement. Caching is the idea of keeping around results of
computations or outside-world-reads so it&#39;s easily accessible the next time
around.</p>
<p>Complications arise when we have different modules at different times being
interested in the same data. And fetching something from memory (cached) is
fundamentally different from, for example, reading it from disk or a remote
host. In JavaScript, the latter is implemented as an asynchronous call. And
since we usually don&#39;t know the order of calls ahead of time we&#39;re left with
having to provide a consistent interface to all callers regardless of where the
data is being fetched from. You&#39;d also need to handle cases where callers ask
for data concurrently. Meaning that we may get another call while we are still
fetching the data and now we&#39;re left to manage calling the clients back in the
right order that they called us in.</p>
<p>The good news is that we can use Promises to:</p>
<ol>
<li>Not have to distinguish between first and subsequent calls</li>
<li>Provide a consistent async interface</li>
<li>Manage callbacks and error propagation</li>
</ol>
<script src="//repl.it/embed/BtUs/11.js"></script>

<p>A more interesting example would be something that needs to change it&#39;s internal
state. However, we need to do it in a way that doesn&#39;t require synchronous and
mutative access to the data. One of our criteria is to blur the distinction between readily
available data and things we haven&#39;t fetched yet. We also don&#39;t want different
mutation calls to effect each other. Ideally, every call would get it&#39;s own copy
of the data that reflect the state of the world at the time of the call.</p>
<p>We can handle this by chaining promise calls that will result in new instances
of the data that will also be cached for future use. Regardless of whether calls
happen concurrently we maintain a strict order of execution and every call will
get a copy of the data without the changes that were made by other callers.</p>
<script src="//repl.it/embed/BtUs/12.js"></script>

<hr>
<h3 id="stores-and-loaders">Stores and Loaders</h3>
<p>Caching can be hard if we have to continually answer the question: Do we have
the data in memory or do we need to fetch it? We just showed how we can use
promises to simplify this. However, it doesn&#39;t take into account function
parameters. A robust caching system has to be able to associate results with
inputs, be it URLs, file names, or arbitrary function parameters. To this end we
can create a store abstraction that will store things in the form of key/values.
But this presents a new challenge of having to synchronize fetching data and
storing it.</p>
<p>You can imagine two <code>get</code> calls to the stores for something we don&#39;t have a
result for yet. Then these two callers would go about concurrently trying to
compute or fetch the data and then come back and try to set it in the store. And
now we have a duplication of work and something akin to a race condition when it
comes to writing the result back to the store. We can add an <code>isFetching</code> flag
to the store but that brings us back to square one of having to manage
callbacks. Here again we can use promises to solve this problem. In addition
to managing callbacks for us they&#39;ll provide something which we can call the
&quot;loader&quot; interface.</p>
<script src="//repl.it/embed/BtUs/9.js"></script>

<p>So instead of having the callers arbitrarily check and set data on the store, we
can instead only expose a <code>get</code> method that will take a key and a loader
function that if called should return a promise for the value. That way the
first time the <code>Cache</code> class encounters a key it will call the loader function
and cache the promise for any subsequent caller.</p>
<h3 id="memoization">Memoization</h3>
<p>So far we&#39;ve seen how we can remove the burden of having to check whether something
is in memory or not at every turn. If we
generalize this a bit we can say that callers should <em>always</em> call functions
regardless of the current state. This is commonly referred to as
memoization and it allows us to build faster programs without compromising on
simplicity. That&#39;s partly why frameworks like React are popular -- it unburdens
the programmer from dealing with stateful objects like the DOM. You <em>always</em> render.
Just like you <em>always</em> call.</p>
<p>All the caching techniques powered by promises that we talked about here can
come in handy when building large programs that conceptually looks like
good old simple and stateless programs without compromising on performance.</p>
<p>My personal experience with this was with building the <a href="https://github.com/facebook/react-native/tree/87245b2d40a865290fbeb4d8f5474fb8b5c1b891/packager">React Native
Packager</a>
and the <a href="https://github.com/facebook/node-haste">module resolver</a>.
One of our goals with React Native is to bring the fast feedback loop we&#39;re used
to in web development to native. However, when we looked at
bundlers in the wild we found that for any sizable project they took
10s of seconds to recompute the bundle after a single file change.
So we had to build our own with performance as the defining feature.</p>
<p>The entire system was built to be lazy and heavily cached using the techniques
outlined in this article. When we get a request for a bundle
we go through and  apply the module resolution algorithm
recursively while reading all the necessary files. And then we compile the files
in parallel and finally combine everything in a single bundle and generate the
sourcemaps. Everyone of those steps requires heavy computation and/or I/O. But
along the way we cache everything at a granular level. Then the next time we
fan-out in the tree of calls to generate the bundle most things will be cached
and the result is instantly returned from memory. The whole thing takes up to a
hundred milliseconds to execute.</p>
<p>When a file changes we invalidate the caches concerning that file and we simulate
a request that would go through entire process again but this time recomputing
parts of the process concerning the changed file (and any other artifacts
affected by it). This will take less than a second to
finish. And by the time the actual request comes in from the client we have
everything cached!</p>
]]></content:encoded>
            <author>amjad.masad@gmail.com (Amjad Masad)</author>
        </item>
        <item>
            <title><![CDATA[Eval as a Service]]></title>
            <pubDate>Sun, 17 Jan 2016 00:00:00 GMT</pubDate>
            <description><![CDATA[ After operating under the radar for a while, we're now publicly launching the [repl.it code evaluation API](https://repl.it/api) that allows anyone to execute code in whatever language from anywhere ...]]></description>
            <content:encoded><![CDATA[<p>After operating under the radar for a while, we&#39;re now publicly launching the
<a href="https://repl.it/api">repl.it code evaluation API</a> that allows anyone to execute
code in whatever language from anywhere on the internet. Here is the story so far:</p>
<p><a href="https://repl.it">repl.it</a> and the underlying tech is a project that grew out
of my frustration from the process of setting up machines to learn
programming. I believed that one of the main turn offs for people wanting to
learn how to code was setting up the development environment. That&#39;s when I
thought that putting a REPL on the web was the best way to get started with programming.</p>
<p>In 2011, and after working on the problem for almost a year we were able to cross-compile
numerous language interpreters to JavaScript and we also hand coded some. We
open sourced everything along the way and little did we know that our work would
help accelerate a revolution in online programming education.</p>
<p>Our <a href="https://github.com/replit">open source code evaluation infrastructure</a> was used by companies like
Codeacademy, Udacity, Bloc, and many others to deliver an in-browser coding
experience. Unfortunately, the way we were
doing things was pushing the envelope for what browsers could do at the time and they would break our code
very often. Coupled with the fact that users had to download megabytes worth
of JavaScript before being able to do anything made it unreliable for websites
serving millions of users all over the world. Since then, I stopped using it in
production in favor for a server-based system and to keep myself honest I
also deprecated the open source project.</p>
<p>After the move, I still got emails from people asking for support on those
projects, and I felt guilty for not being able to help. At the same time
repl.it was  growing and with it my wallet was
shrinking. One of the benefits of doing client-side code evaluation was that the cost
was practically zero. I considered putting ads on the site but I
couldn&#39;t do this to our users. Especially because many of them happen to be
students learning as part of classrooms:</p>
<div id="fb-root"></div>
<script>(function(d, s, id) {
  var js, fjs = d.getElementsByTagName(s)[0];
  if (d.getElementById(id)) return;
  js = d.createElement(s); js.id = id;
  js.src = "//connect.facebook.net/en_US/sdk.js#xfbml=1&version=v2.5";
  fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));</script>

<div class="fb-post"
data-href="https://www.facebook.com/amasad9/posts/772878056174859?pnref=story"
data-width="750">
<div class="fb-xfbml-parse-ignore">
<blockquote cite="https://www.facebook.com/amasad9/posts/772878056174859">
<p>Yesterday we
visited a high school in Mountain View where the entire school were learning how
to code. Hundreds of...</p>Posted by <a href="#" role="button">Amjad Masad</a>
on&nbsp;
<a href="https://www.facebook.com/amasad9/posts/772878056174859">Saturday, October
24, 2015</a></blockquote></div></div>

<p>After getting so many emails from people asking for support I decided to offer
our code <a href="https://repl.it/api">evaluation infrastructure as a service</a>. Since then we had a few customers use us -- enough to cover repl.it&#39;s cost. More than anything, I&#39;m happy that our customers
are deriving a lot of value from the service and in many cases they&#39;re building
things in line with our mission of democratizing programming. For
example, Carnegie Mellon University is using us as part of their online open
learning initiative. Flatiron school and Trinket are using us to build their online education
platforms. Oneinterview and Airety are using us to deliver online interviewing
services. And of course repl.it uses the same API for the main site, and the
<a href="http://amasad.me/2015/04/09/hello-world/">embeds</a>.</p>
<p>I&#39;m planning to do a technical write up about the tech and architecture behind
the service but the basic idea is that you connect to our servers and then send
us programs to execute. It&#39;s fast, reliable, and scalable. Try out at
<a href="https://repl.t">repl.it</a>. And check out the <a href="https://repl.it/api">API page</a> for
more information. Here is what an API call looks like for a &quot;Hello World&quot; in
Ruby:</p>
<pre><code class="lang-js"><span class="hljs-keyword">var</span> repl = <span class="hljs-keyword">new</span> ReplitClient(<span class="hljs-string">'api.repl.it'</span>, <span class="hljs-number">80</span>, <span class="hljs-string">'ruby'</span>, token);
repl.connect().then(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> repl.evaluate(
  <span class="hljs-string">'puts "hello world"'</span>,
  { <span class="hljs-attr">stdout</span>: <span class="hljs-function"><span class="hljs-params">out</span> =&gt;</span> <span class="hljs-built_in">console</span>.log(out) }
));
</code></pre>
<p>What started as something that I thought of as a necessary annoyance to keep the
site running turned out to be something that I&#39;m actually proud of. This
wouldn&#39;t have been possible without the work from <a href="http://twitter.com/hayaodeh">Haya</a> and Faris where they
continue to build awesome new features and products on top of repl.it.</p>
]]></content:encoded>
            <author>amjad.masad@gmail.com (Amjad Masad)</author>
        </item>
        <item>
            <title><![CDATA[The Stoic of Open Source]]></title>
            <pubDate>Wed, 13 Jan 2016 00:00:00 GMT</pubDate>
            <description><![CDATA[ Two unrelated things happened recently:  1. A few high profile open source maintainer burnouts<sup>1</sup> 2. I've been reading a lot of philosophy<sup>2</sup>  I was first introduced to Stoicism by ...]]></description>
            <content:encoded><![CDATA[<p>Two unrelated things happened recently:</p>
<ol>
<li>A few high profile open source maintainer burnouts<sup>1</sup></li>
<li>I&#39;ve been reading a lot of philosophy<sup>2</sup></li>
</ol>
<p>I was first introduced to Stoicism by a friend who recommended the book <a href="http://www.amazon.com/Guide-Good-Life-Ancient-Stoic/dp/0195374614">A Guide
to the Good
Life</a>. And
they kept coming up whenever I&#39;m reading about philosophy, and for good reason,
they&#39;re a cool bunch.</p>
<p>Stoics understood that you can never depend on external factors for happiness
and that the only way to achieve a sense of well-being is to be internally
satisfied. However, unlike the cynics or the skeptics, they <em>can</em> derive
happiness from the external world. In other words, <strong>they get all the upside
while avoiding downside</strong>. This sounds amazing, and at first glance it sounds a
bit like Buddhism, but I think the defining feature of Stoicism is their use of
psychological tricks and reasoning to achieve their goal of tranquility. That&#39;s
why I think it may resonate with the programmer community. Maybe we can learn
something from them about open source maintenance?</p>
<h2 id="insults-and-attacks">insults and attacks</h2>
<p>One thing that angers me -- and I see angers many open source
maintainers -- is the harsh criticism mixed with personal attacks that some
users launch against maintainers. There could be thousands of satisfied
users but a handful of loud and vile individuals could make your life
miserable. This can be related to how the Stoics dealt with insults. And they
had a lot to say about the subject.</p>
<p>Epictetus recommended that we pause to consider our insulter. If he is a fool then
rather than become angry or hurt, we should feel relief over his disapproval and
insults. Indeed, <strong>we should be more concerned if we find the fool agreeing with
us</strong><sup>3</sup>. It goes without saying that someone launching personal attacks
against you for providing your work free of charge, is a fool.</p>
<blockquote>
<p>Begin each day by telling yourself: Today I shall be meeting with interference,
ingratitude, insolence, disloyalty, ill-will, and selfishness -- all of them
due to the offenders’ ignorance of what is good or evil?</p>
</blockquote>
<blockquote>
<p>-- Marcus Aurelius</p>
</blockquote>
<p>If you are putting yourself and your work in the public eye then it&#39;s very
likely that you&#39;re going to have a run-in with the above-mentioned unpleasant
people. So accept it as a reality and learn to deal with it.</p>
<p>Seneca suggests a potentially more useful way of dealing with insults:</p>
<blockquote>
<p>Why is it an insult, to be told what is self-evident?</p>
</blockquote>
<p>If you found that there is some truth in the attack. Then simply extract that
knowledge as constructive feedback and use it to improve yourself and your project.</p>
<p>Those are some tools we can use to reason out the sting of the insult, but
what do we do about it? do we have to reply? The Stoics advocated two main ways of
responding to insults:</p>
<ol>
<li>Humor</li>
<li>Refusing to respond</li>
</ol>
<p>By simply laughing off an insult, we are implying that the insult and insulter
are not to be taken seriously therefore stripping them of any legitimacy that would
otherwise be implied if we replied seriously to their insult. Here are a couple
of amusing anecdotes from Seneca:</p>
<blockquote>
<p>Seneca points approvingly to Cato’s use of humor to deflect a particularly
grievous insult. Cato was pleading a case when an adversary named Lentulus spit
in his face. Rather than getting angry or returning the insult, Cato calmly
wiped off the spit and said, “I will swear to anyone, Lentulus, that people are
wrong to say that you cannot use your mouth!” Seneca also approves of Socrates’
response to an even more abusive insult.  Someone once came up to Socrates and,
without warning, boxed his ears. Rather than getting angry, Socrates made a joke
about what a nuisance it is, when we go out, that we can never be sure whether
or not to wear a helmet. <sup>4</sup></p>
</blockquote>
<p>If you are quick-witted then this type of humor may come naturally to you, but I&#39;m
not. And, paradoxically, spending a lot of much time coming up with the perfect comeback
will have the negative effect of dwelling over the insult. Therefore the best
thing to do is act as if it never happened. This, first of all, robs them
of the pleasure of having upset us. And also shows everyone in the community
that we can&#39;t be bothered with childish behavior and we have more important
things to attend to (such as maintaining the project).</p>
<h2 id="on-making-mistakes">on making mistakes</h2>
<p>Everyone makes mistakes, and open source maintainers are no exception. You&#39;ll
eventually push a breaking change that will unleash a mob of semver purists
gunning for your head (refer to the previous section on how to deal with
obnoxious people). Here, I&#39;ll talk about how you should reason about the fact
that you made a mistake.</p>
<blockquote>
<p>Truths about the past are necessary: it is not merely that they aren&#39;t other
than they are—they can&#39;t be other than they are, for nothing has the power to
change the past -- Epictetus</p>
</blockquote>
<p>Stoics were pioneers of logic, and it followed from their use of logic that
we should have a fatalistic attitude towards the past. We just learn from our
mistakes and move on -- there could have never been a world where you have not made
that mistake. Because without that event happening the world where you are now
looking back at that mistake doesn&#39;t exist. The last part was me going out on a
limb, but all this to say is that you can&#39;t change the past and there is no
point in feeling regret.</p>
<p>Mistakes may help you revise and strengthen your processes and tests. It may
even get your users to be more involved in the project&#39;s maintenance because they
see you as someone needing their help. I doubt that any one mistake has ever
caused the failure of an open source project, the important thing is to learn
and move on.</p>
<h2 id="work-on-your-own-terms">work on your own terms</h2>
<p>Taking a utilitarian approach to open source seems to be the best and most
sustainable. In the JS Infra team at
Facebook we have the following dictum:</p>
<blockquote>
<p>We only open source what we use in production</p>
</blockquote>
<p>When we stop using something internally we either find a new home for it or
simply deprecate it. This puts us in a better position to serve our community. Similarly, you
can approach your personal open source projects with the same attitude. Keep
your project focused and fully aligned with your needs.</p>
<p>For example, if someone sends you pull request for a feature that you are not
going to use yourself and don&#39;t have the time test and maintain, then simply refuse it. It&#39;s
better to be focused in scope than to make the project suitable for every
possible use case while increasing your chances of burnout.</p>
<blockquote>
<p>Nothing is worth doing pointlessly -- Marcus Aurelius</p>
</blockquote>
<p>People looking from the outside at open source are often amazed by how a
world based on altruism could exist. Sorry, it doesn&#39;t. A lot can be gained from
participating in open source. Slaving away with no explicit goal is a recipe
for disaster. I&#39;m not saying that helping others is not a valid a
goal -- it could be, however, it should be intentional.</p>
<blockquote>
<p>It is impossible that happiness, and yearning for what is not present, should
ever be united -- Epictetus</p>
</blockquote>
<p>Try not tie your identity and sense of well-being to your open source
project. Align your needs with the community, get the upside of any contributions and
popularity. But try not to get affected by any downside.</p>
<hr>
<p><small>
[1] I&#39;ve never been a sole creator/maintainer of a massively popular open
source project, however, I work as part of teams on massively popular open
source projects. So I probably don&#39;t understand the magnitude of stress sole
maintainers may feel.</p>
<p>[2] My favorite books so far: A History of Western Philosophy by Bertrand Russel,
The Guide to the Good Life by William Braxton, and the Philosophize This! podcast.</p>
<p>[3] Great <a href="http://throughablogdarkly.blogspot.com/2012/12/stoicism-dealing-with-insults.html?m=1">blogpost</a> summarizing how the Stoics dealt with insults</p>
<p>[4] A passage from The Guide to The Good Life
</small></p>
]]></content:encoded>
            <author>amjad.masad@gmail.com (Amjad Masad)</author>
        </item>
        <item>
            <title><![CDATA[Overcoming Intuition in Programming]]></title>
            <pubDate>Sun, 03 Jan 2016 00:00:00 GMT</pubDate>
            <description><![CDATA[ In a [series of experiments](http://faculty.chicagobooth.edu/nicholas.epley/alteretal.pdf), researchers set out to discover the relationship between difficulty or "disfluency" and cognition. They pre...]]></description>
            <content:encoded><![CDATA[<p>In a <a href="http://faculty.chicagobooth.edu/nicholas.epley/alteretal.pdf">series of experiments</a>,
researchers set out to discover the relationship between difficulty or
&quot;disfluency&quot; and cognition. They presented the same test to two groups, one in
an easy to read (intuitive) format and the other in a difficult (disfluent)
format. And in all the experiments they carried out, the disfluency group scored
substantially higher. The theory behind this is that people will default to
relying on the automatic, effortless, and primitive system for reasoning. But if
things are counter-intuitive or harder to understand we switch to the deeper,
deliberate and analytical mode of thinking.</p>
<p>I&#39;ve been thinking about how this translates to programming. Programming is an
intellectually challenging task, but luckily we invent tools to make it
manageable. I find that up to a certain point, the intuitive and easy properties
of a given language, framework, or library might start to have negative
effects. From personal experience and from mentoring beginners I noticed that
when using tools that allow us to reason within our intuition, anytime we&#39;re
faced with some difficulty we feel that we&#39;ve done something wrong. And although
we might have the necessary skills to overcome the difficulty, we often start
questioning and revising our work. Asking questions about best practices
relative to the framework instead of programming our way out. The quintessential
example of this is the Stack overflow questions for <em>&quot;how do I use jQuery to do
X?&quot;</em> or the answers <em>&quot;use jQuery [plugin] to do X&quot;</em> where X could be anything from
basic arithmetic to websockets.</p>
<h3 id="the-framework-negative-space">The framework negative space</h3>
<p>When using a framework, a certain class of problems are made easy to
solve. Programming feels intuitive if we stay within that space created by the framework. We
may refer to this as the <strong>framework intuitive space</strong>. On the other hand we may refer to the
rest of the space that framework doesn&#39;t solve or have an opinion on
as the <strong>framework negative space</strong>. The negative space
is not necessarily a defect of the framework, it&#39;s just not in the space the
framework was built to solve. However, having put the programmer in the intuitive space for a
long stretch of time, it makes it feel out of place when finding oneself in the
negative space.</p>
<p>When the beginner programmer find themselves in the negative space, they often
look to the library authors to put them back in the intuitive space. That&#39;s why
for any popular framework you find that there is an entire ecosystem of plugins
and addons that extends the framework&#39;s intuitive space to cover an increasingly
growing surface area. It doesn&#39;t seem to be inherently wrong if it makes
programmers more productive. However, it may have unintended negative consequences:</p>
<ol>
<li>Increased reliance from the programmer on the ecosystem&#39;s library authors</li>
<li>Offloading of architectural decisions to the libraries all the while
incurring technical debt</li>
<li>Enabling the false belief that programming should always feel intuitive</li>
</ol>
<h3 id="the-developer-and-library-author-codependency">The developer and library author codependency</h3>
<p>I should start by saying that this is technically a false dichotomy. All programmers
take on both those roles in any programming session. You maybe coding the product
business logic and switch to building a general purpose abstraction to help you
in multiple places in your codebase. However, I&#39;ve noticed that in open-source, people tend
to act in a manner that makes this dichotomy seem true.</p>
<p>The easiest way I&#39;ve found to succeed in open source is to pave the negative
framework space to become an intuitive space. In other words, writing the
plugins and extensions. As a framework becomes more popular, a growing number of
developers (usually beginners) will start complaining about how it&#39;s hard to do
X in this framework (and as we&#39;ve seen X might be totally unrelated). Now, as in
the business world, open-source is extremely competitive and as soon as there
is an opening to solve a perceived problem for a lot of people, many would rise
up to the occasion. This becomes an enabler to the false belief that a
programmer can spend all of their time programming in the intuitive space.</p>
<h3 id="conclusion">Conclusion</h3>
<p>I think fixing this problem ultimately comes down to education. Very early on
when someone is learning programming our culture tend to emphasize an obsession with
tooling. I get a lot of questions from aspiring programmers on what&#39;s the best
tool or languages to learn. It&#39;s almost always a premature question to ask. I
used to come up with answers like &quot;depending on what you&#39;re building&quot; or &quot;pick a
beginner friendly community&quot; or &quot;invest in a growing language&quot;. I
think all of these are good answers, but it doesn&#39;t really matter that early on
in a programmer&#39;s learning journey. It&#39;s all the same when you&#39;re
essentially learning how to compute. Furthermore, these sort of answers enable
the culture of tooling obsession.</p>
<p>Code reuse, libraries, sharing, and open-source are very important to software
engineering, but we should be careful to not enable the belief that programming
should be as easy as gluing things together. In fact, these days I&#39;m often
skeptical when things feel a little bit too easy. If programming was as easy as
this then it would&#39;ve already been automated away.</p>
]]></content:encoded>
            <author>amjad.masad@gmail.com (Amjad Masad)</author>
        </item>
        <item>
            <title><![CDATA[Easier Concurrent Programming in JavaScript with Async Functions]]></title>
            <pubDate>Sat, 31 Oct 2015 00:00:00 GMT</pubDate>
            <description><![CDATA[ We're about to introduce async functions internally at Facebook so I'm taking the time to  reflect on how this could be a great win for building reliable software.  When I joined the company, I worke...]]></description>
            <content:encoded><![CDATA[<p>We&#39;re about to introduce async functions internally at Facebook so
I&#39;m taking the time to  reflect on how this could be a great win for building
reliable software.</p>
<p>When I joined the company, I worked on a team tasked with improving
photo upload reliability on the site. We were failing 1 out of 10
people that tried to upload a photo album. Which translates to
millions of people having terrible experiences on daily basis. One of the first
things that we struggled with was understanding the ordering of
operations. The system was made up of multiple components (Flash for
image re-sizing, UIs, Controllers, Servers) that had to asynchronously
communicate via JS and was all done in callbacks. This made debugging
really hard. Sometimes callbacks will get lost and never get called,
at times they will be called multiple times, sometimes errors will
occur after the callback is called and never gets reported. Not to
mention all the horrible race conditions that we saw. And this is not something
that is limited to Facebook, or that can only happen at our scale. I
was in similar situations at small startups too. This can happen in
any sizable (potentially distributed) system written in JavaScript
using callbacks.</p>
<p>When I first started learning JavaScript, one of things people praised
it for was: &quot;easy concurrent programming&quot;. The argument goes &quot;it&#39;s a
single-threaded process with a strict run-to-completion programming
model and that means you can&#39;t have race conditions&quot;. Turns out that
can&#39;t be further from the truth. The definition of race conditions is
not tied to multithreading. It is simply when you have a system that
is dependent on the sequence of events from multiple components and
then the components behave in an unintended way. Which brings me to the
point of this post. I want to show that using async functions (or
generally co-routines) you can write programs that makes the expected
ordering of events explicit and makes it easier to recover from
failures in subcomponents.</p>
<p>I will illustrate this by going through an example of building a
vending machine. Everything in the vending machine costs 1 cent, but
the machine can take in any coin that is worth any arbitrary number of
cents. A sample run of this machine:</p>
<ul>
<li>Insert a quarter</li>
<li>Select an item</li>
<li>Dispense the item</li>
<li>Return 24 cents change</li>
</ul>
<p>Here is my initial implementation:</p>
<ul>
<li>A <code>VendingMachine</code> class with two public methods</li>
<li><code>coin(value)</code> inputs a coin with a given value in cents to the machine</li>
<li><code>select(item)</code> inputs an item selection to the machine</li>
<li>Two subcomponents <code>itemDispenser</code> and <code>change</code> resoponsible for
dispensing the items and returning the change respectively</li>
</ul>
<pre><code class="lang-javascript"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">VendingMachine</span> </span>{
  coin(value) {
    <span class="hljs-keyword">this</span>.cents = value;
  }

  select(item) {
    <span class="hljs-keyword">this</span>.itemDispenser.dispense(item, () =&gt; {
      <span class="hljs-keyword">this</span>.change.<span class="hljs-keyword">return</span>(<span class="hljs-keyword">this</span>.cents - <span class="hljs-number">1</span>);
    });
  }
}
</code></pre>
<p>Simple enough. But of course it&#39;s missing a few things. First of
all there is no error handling:</p>
<ul>
<li>What if the <code>itemDispenser</code> failed? We should of course return all the money.</li>
<li>What if the <code>change</code> component failed? We should get into broken
state so we don&#39;t accept any more coins until someone fixes the
machine.</li>
</ul>
<p>Let&#39;s add error handling and a broken state.</p>
<pre><code class="lang-javascript"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">VendingMachine</span> </span>{
  coin(value) {
    <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.broken){
      console.error(<span class="hljs-string">'Out of order'</span>);
      <span class="hljs-keyword">return</span>;
    }

    <span class="hljs-keyword">this</span>.cents = value;
  }

  select(item) {
    let change = <span class="hljs-keyword">this</span>.cents - <span class="hljs-number">1</span>;
    <span class="hljs-keyword">this</span>.itemDispenser.dispense(item, e =&gt; {
      <span class="hljs-keyword">if</span> (e) {
        console.error(e.message);
        <span class="hljs-comment">// Failed to dispense item, return all the money.</span>
        change = <span class="hljs-keyword">this</span>.cents;
      }

      <span class="hljs-keyword">this</span>.change.<span class="hljs-keyword">return</span>(change, e =&gt; {
        <span class="hljs-keyword">if</span> (e) {
          <span class="hljs-keyword">this</span>.broken = <span class="hljs-literal">true</span>;
        }
      })
    });
  }
}
</code></pre>
<p>Now that we can handle errors from the machine components. What if the
outside world behaved in an unintended way? In other words, what
if someone selected an item without paying? What if someone inserted
two coins without selecting an item? Ideally we&#39;d have input queuing,
but let&#39;s keep it simple for now.</p>
<pre><code class="lang-javascript"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">VendingMachine</span> </span>{
  coin(value) {
    <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.broken){
      console.error(<span class="hljs-string">'Out of order'</span>);
      <span class="hljs-keyword">return</span>;
    }

    <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.cents) {
      console.error(<span class="hljs-string">'Processing existing order'</span>);
      <span class="hljs-keyword">return</span>;
    }

    <span class="hljs-keyword">this</span>.cents = value;
  }

  select(item) {
    <span class="hljs-keyword">if</span> (!<span class="hljs-keyword">this</span>.cents) {
      console.error(<span class="hljs-string">'Please insert a coin'</span>);
      <span class="hljs-keyword">return</span>;
    }

    let change = <span class="hljs-keyword">this</span>.cents - <span class="hljs-number">1</span>;
    <span class="hljs-keyword">this</span>.itemDispenser.dispense(item, e =&gt; {
      <span class="hljs-keyword">if</span> (e) {
        console.error(e.message);
        <span class="hljs-comment">// Failed to dispense item, return all the money.</span>
        change = <span class="hljs-keyword">this</span>.cents;
      }

      <span class="hljs-keyword">this</span>.change.<span class="hljs-keyword">return</span>(change, e =&gt; {
        <span class="hljs-keyword">if</span> (e) {
          <span class="hljs-keyword">this</span>.broken = <span class="hljs-literal">true</span>;
        }
        <span class="hljs-keyword">this</span>.cents = <span class="hljs-number">0</span>;
      })
    });
  }
}
</code></pre>
<p>Can you spot the potential race condition?
What if you inserted a coin, selected an item, then before the machine
gets a chance to dispense the item and return the change you selected
another item? We should make sure <code>this.cents</code> is updated right after
the selection.</p>
<pre><code class="lang-javascript"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">VendingMachine</span> </span>{
  coin(value) {
    <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.broken){
      console.error(<span class="hljs-string">'Out of order'</span>);
      <span class="hljs-keyword">return</span>;
    }

    <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.cents) {
      console.error(<span class="hljs-string">'Processing existing order'</span>);
      <span class="hljs-keyword">return</span>;
    }

    <span class="hljs-keyword">this</span>.cents = value;
  }

  select(item) {
    <span class="hljs-keyword">if</span> (!<span class="hljs-keyword">this</span>.cents) {
      console.error(<span class="hljs-string">'Please insert a coin'</span>);
      <span class="hljs-keyword">return</span>;
    }

    let change = <span class="hljs-keyword">this</span>.cents - <span class="hljs-number">1</span>;
    <span class="hljs-comment">// Immediately update to avoid race conditions</span>
    <span class="hljs-keyword">this</span>.cents = <span class="hljs-number">0</span>;

    <span class="hljs-keyword">this</span>.itemDispenser.dispense(item, e =&gt; {
      <span class="hljs-keyword">if</span> (e) {
        console.error(e.message);
        <span class="hljs-comment">// Failed to dispense item, return all the money.</span>
        change += <span class="hljs-number">1</span>;
      }

      <span class="hljs-keyword">this</span>.change.<span class="hljs-keyword">return</span>(change, e =&gt; {
        <span class="hljs-keyword">if</span> (e) {
          <span class="hljs-keyword">this</span>.broken = <span class="hljs-literal">true</span>;
        }
        <span class="hljs-keyword">this</span>.cents = <span class="hljs-number">0</span>;
      })
    });
  }
}
</code></pre>
<p>But wait, are we really done? What if you inserted a coin, selected an
item, and then immediatly inserted another coin? That coin is then
lost in limbo. We should gaurd the entire the process with another
state variable. But the problem is that every time we add a state
variable it makes the program harder to understand and
test, and presents more race hazards. Who would&#39;ve thought a program
with two input events can be so complex to build reliabily. I&#39;ll spare
you anymore inspection and iteration and directly jump to what
any sensible programmer would do when presented with this
challenge: build a state machine.</p>
<pre><code class="lang-javascript"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">VendingMachine</span> </span>{
  <span class="hljs-keyword">constructor</span>() {
    <span class="hljs-keyword">this</span>.state = IDLE;
    <span class="hljs-keyword">this</span>.queue = [];
  }

  coin(coin) {
    <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.state === BROKEN) {
      <span class="hljs-keyword">return</span> console.error(<span class="hljs-string">'Machine broken'</span>);
    }

    <span class="hljs-keyword">this</span>.queue.push(coin);
    <span class="hljs-keyword">this</span>.dispatch();
  }

  dispatch() {
    <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.state !== IDLE) {
      <span class="hljs-keyword">return</span>;
    }

    <span class="hljs-keyword">this</span>.cents = <span class="hljs-keyword">this</span>.queue.shift();
    <span class="hljs-keyword">this</span>.state = WAIT_FOR_SELECT;
  }

  <span class="hljs-keyword">break</span>(err) {
   console.error(err.message);
   <span class="hljs-keyword">this</span>.state = BROKEN;
  }

  select(item) {
    <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.state === IDLE) {
      <span class="hljs-keyword">return</span> console.error(<span class="hljs-string">'Please insert coin'</span>);
    }

    <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.sate !== WAIT_FOR_SELECT) {
      <span class="hljs-keyword">return</span> console.error(<span class="hljs-string">'Processing existing order'</span>);
    }

    let change = <span class="hljs-keyword">this</span>.cents - <span class="hljs-number">1</span>;
    <span class="hljs-keyword">this</span>.itemDespenser.despense(item, err =&gt; {
      <span class="hljs-keyword">if</span> (err) {
        console.error(<span class="hljs-string">'Error dispensing item'</span>);
        change += <span class="hljs-number">1</span>;
        <span class="hljs-keyword">return</span>;
      }

      <span class="hljs-keyword">this</span>.change.<span class="hljs-keyword">return</span>(change, err =&gt; {
        <span class="hljs-keyword">if</span> (err) {
          <span class="hljs-keyword">this</span>.<span class="hljs-keyword">break</span>(err);
          <span class="hljs-keyword">return</span>;
        }
        <span class="hljs-keyword">this</span>.state = IDLE;
        <span class="hljs-keyword">this</span>.dispatch();
      });
    });
  }
}
</code></pre>
<p>I think I got it right. But who knows, you wouldn&#39;t know by reading
the program, you&#39;d need to write a lot of unit tests to convince
yourself that it works. And then write some pseudocode in comments to
explain what you intended to do here for future programmers. But even
then there is room for failure. One of the subcomponents can call our
callback multiple times causing all kind of failures to happen.</p>
<p>Now that we&#39;ve explored how hard building something -- that is
conceptually easy -- using callbacks can be. Let&#39;s try with a
better concurrency primitive, namely async functions.</p>
<p><em>If you&#39;re not familiar with async functions, <a href="https://jakearchibald.com/2014/es7-async-functions/">read this intro
first</a>.</em></p>
<p>Here&#39;s how we&#39;ll structure our code for the <code>async</code> version:</p>
<ul>
<li>We&#39;ll be using a data-structure called <code>PromiseQueue</code> (it&#39;s really
simple and can be implemented in ~20 lines of code)</li>
<li>A <code>PromiseQueue</code> has two methods <code>put</code> and <code>get</code>. <code>get</code> would return
a promise that can only be resolved once we put something into the queue</li>
<li>We&#39;ll be using two promise queues, one for the coins and one for the
items</li>
<li>We&#39;ll have a main run loop that will run indefinitely or until the
machine breaks</li>
</ul>
<pre><code class="lang-javascript"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">VendingMachine</span> </span>{
  <span class="hljs-keyword">constructor</span>() {
    <span class="hljs-keyword">this</span>.coins = new PromiseQueue();
    <span class="hljs-keyword">this</span>.items = new PromiseQueue();
    <span class="hljs-keyword">this</span>.brokenErr = e;
    <span class="hljs-keyword">this</span>.run().<span class="hljs-keyword">catch</span>(e =&gt; <span class="hljs-keyword">this</span>.brokenErr = e);
  }

  coin(coin) {
    <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.brokenErr) {
      <span class="hljs-keyword">return</span> console.error(<span class="hljs-string">'Machine broken'</span>, <span class="hljs-keyword">this</span>.brokenErr);
    }
    <span class="hljs-keyword">this</span>.coins.put(coin);
  }

  select(item) {
    <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.brokenErr) {
      <span class="hljs-keyword">return</span> console.error(<span class="hljs-string">'Machine broken'</span>, <span class="hljs-keyword">this</span>.brokenErr);
    }
    <span class="hljs-keyword">this</span>.items.put(item);
  }

  async run(item) {
    <span class="hljs-keyword">while</span> (<span class="hljs-number">1</span>) {
      let cents = await <span class="hljs-keyword">this</span>.coins.<span class="hljs-keyword">get</span>();
      let item = await <span class="hljs-keyword">this</span>.items.<span class="hljs-keyword">get</span>();
      let change = cents - <span class="hljs-number">1</span>;

      <span class="hljs-keyword">try</span> {
        await <span class="hljs-keyword">this</span>.itemDispenser.dispense(item);
      } <span class="hljs-keyword">catch</span> (e) {
        console.error(<span class="hljs-string">'Error dispensing item'</span>);
        change = cents;
      }

      <span class="hljs-keyword">try</span> {
        await <span class="hljs-keyword">this</span>.change.<span class="hljs-keyword">return</span>(change);
      } <span class="hljs-keyword">catch</span> (e) {
        console.error(<span class="hljs-string">'Error returning change'</span>);
        <span class="hljs-keyword">throw</span> e;
      }
    }
  }
}
</code></pre>
<p>Look how beautiful this is. Everything you need to know about the program you&#39;ll know by
reading the <code>run</code> function. A single function that reads exactly like
how we described the machine should work. We are even using elementary
control flow, like try/catch, and while loops! What&#39;s more, the entire state
of the machine are basically local variables. That leaves less room
for races to happen. Which brings me to the conclusion:</p>
<blockquote>
<p><a href="http://eli.thegreenplace.net/2009/08/29/co-routines-as-an-alternative-to-state-machines/">Co-routines are to state machines what recursion is to stacks</a></p>
</blockquote>
<p>Co-routines are the generalized form of async functions. Where async
functions can only pause execution while waiting on a promise,
co-routines allow
multiple entry points for functions to suspend and resume
execution. <a href="http://tobyho.com/2013/06/16/what-are-generators/">ES6
generator
functions</a> are an
example of a generalized co-routines. So, similar to how recursion
can help process nested data-structures without using explicit stacks,
co-routines helps solve problems involving state without using explicit state machines.</p>
]]></content:encoded>
            <author>amjad.masad@gmail.com (Amjad Masad)</author>
        </item>
        <item>
            <title><![CDATA[Hello World]]></title>
            <pubDate>Thu, 09 Apr 2015 00:00:00 GMT</pubDate>
            <description><![CDATA[ You can now embed runnable code snippets from [repl.it](https://repl.it) on your blog or website. Just go to [repl.it](https://repl.it) and pick one of the languages listed below, save your code and ...]]></description>
            <content:encoded><![CDATA[<p>You can now embed runnable code snippets from <a href="https://repl.it">repl.it</a> on your blog or website.
Just go to <a href="https://repl.it">repl.it</a> and pick one of the languages listed below, save your code and click share to get the html code to paste on your site.</p>
<h4 id="c-">C++</h4>
<p><script src="//repl.it/embed/iAR.js"></script></p>
<div>&nbsp;</div>

<h4 id="c">C</h4>
<p><script src="//repl.it/embed/iAS.js"></script></p>
<div>&nbsp;</div>

<h4 id="ruby">Ruby</h4>
<p><script src="//repl.it/embed/iAm.js"></script></p>
<div>&nbsp;</div>

<h4 id="python-3">Python 3</h4>
<p><script src="//repl.it/embed/iAo.js"></script></p>
<div>&nbsp;</div>

<h4 id="node">Node</h4>
<p><script src="//repl.it/embed/iAp.js"></script></p>
<div>&nbsp;</div>

<h4 id="go">Go</h4>
<p><script src="//repl.it/embed/iAr.js"></script></p>
<div>&nbsp;</div>

<h4 id="java">Java</h4>
<p><script src="//repl.it/embed/iAs.js"></script></p>
<div>&nbsp;</div>
]]></content:encoded>
            <author>amjad.masad@gmail.com (Amjad Masad)</author>
        </item>
        <item>
            <title><![CDATA[Lesser-Known JavaScript Debugging Techniques]]></title>
            <pubDate>Sun, 09 Mar 2014 00:00:00 GMT</pubDate>
            <description><![CDATA[ After I prototype an app I'm building, my time is split between the editor and the browser with the console open. I try to debug as I go to avoid creating a complete mess. Moreover, when I get a bug ...]]></description>
            <content:encoded><![CDATA[<p>After I prototype an app I&#39;m building, my time is split between the editor and the browser with the console open. I try to debug as I go to avoid creating a complete mess. Moreover, when I get a bug report for a production app the first thing that I do is try to debug using Chrome devtools, and I usually find the bug without touching my editor. To be effective at that, I had to learn a great deal about the tools available and in this post I’m going to shed light on the lesser-known features and techniques of JavaScript debugging.</p>
<h2 id="command-line-api">Command Line API</h2>
<p>Started by Firebug and currently implemented in all browsers with a debugger. It has <a href="https://getfirebug.com/wiki/index.php/Command_Line_API">many useful</a> utility functions such as <code>$</code>, <code>$0</code>, <code>keys</code>, <code>values</code> etc. and I highly encourage you to <a href="https://developers.google.com/chrome-developer-tools/docs/commandline-api">learn everything about them</a>.</p>
<p>Until recently, Chrome DevTools <a href="https://code.google.com/p/chromium/issues/detail?id=168776">didn&#39;t implement</a> the full API, and even after they did, a lot went <a href="https://developers.google.com/chrome-developer-tools/docs/commandline-api">undocumented</a>. The most useful of those functions are:</p>
<h3 id="debug-and-monitor">debug and monitor</h3>
<p>If you basically live in the console like I do you&#39;d want to be able to add breakpoints to function references without having to go to the source and find the function, especially when debugging production apps with minified source or built source with no source maps.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-title">debug</span><span class="hljs-params">(ExampleApp.exampleFunction)</span></span>
</code></pre>
<p>Now every time the <code>ExampleApp.exampleFunction</code> is called the debugger will be invoked. To turn it off simply call <code>undebug</code> on the same function.</p>
<p>However, you often just need to know if the function was called and the arguments passed to it, for that you can use <code>monitor</code> and <code>unmonitor</code>.</p>
<h2 id="setting-up-traps">Setting up traps</h2>
<p>When working on a complex system with many modules, it&#39;s impossible to know what every part is doing. Beyond the typical <code>console.log</code>ing and breakpoint insertion, a good debugging technique is setting up traps with debugger statements to stop and get an idea of what&#39;s going on.</p>
<p><blockquote class="twitter-tweet" lang="en"><p>Just debugged a link-not-working issue by doing <code>Event.prototype.preventDefault = function () { debugger; };</code>. Feeling pretty smooth.</p>&mdash; Domenic Denicola (@domenic) <a href="https://twitter.com/domenic/statuses/441758861649661952">March 7, 2014</a></blockquote></p>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

<p>For a long time I&#39;ve had a library of functions that I copy-pasted around to help set up traps. But after a round of polishing I&#39;m releasing it as a stand-alone JavaScript library and a chrome extension called <a href="https://github.com/amasad/debug_utils">Debug Utils</a>. You can find it on <a href="https://github.com/amasad/debug_utils">GitHub</a> and can install it directly from the <a href="https://chrome.google.com/webstore/detail/debug-utils/djailkkojeahmihdpcelmmobkpepmkcl">Chrome Webstore</a>.</p>
<h2 id="enter-debugutils">Enter DebugUtils</h2>
<h3 id="break-on-native-method-call">Break on native method call</h3>
<p>Unfortunately <code>debug</code> and <code>monitor</code> don&#39;t work on native methods so you need to wrap native methods with functions containing a <code>debugger</code> statement, similar to the tweet above, except you probably would want to call the original function after the <code>debugger</code> statement. In DebugUtils this is called <code>$dum</code> (short for debug utils method).</p>
<pre><code class="lang-js"><span class="hljs-constructor">$dum(Event.<span class="hljs-params">prototype</span>, '<span class="hljs-params">preventDefault</span>')</span>;
</code></pre>
<h3 id="break-on-custom-events">Break on custom events</h3>
<p>The Command Line API provides a <a href="https://developers.google.com/chrome-developer-tools/docs/commandline-api#monitoreventsobject_events"><code>monitorEvents</code></a> function which is great for debugging DOM events, but it won&#39;t work for custom events. For that you want to setup your own debugger or logger function as a handler to an event on an object. In DebugUtils this is called <code>$duv</code> (short for debug utils events).</p>
<pre><code class="lang-js"><span class="hljs-constructor">$duv(<span class="hljs-params">exampleModule</span>, '<span class="hljs-params">data</span>')</span>;
</code></pre>
<h3 id="break-on-property-access">Break on property access</h3>
<p>Often times, objects can start changing from under your feet. You can <a href="http://johnkpaul.com/blog/2013/07/20/break-on-property-change/">setup object getters and setters</a> containing a  <code>debugger</code> statement to find out what part of the code is responsible. When something changes a given property on your object you will stop and be able to trace back what&#39;s changing it. In DebugUtils this is called <code>$dus</code>:</p>
<pre><code class="lang-js"><span class="hljs-constructor">$dus(<span class="hljs-params">exampleObject</span>, '<span class="hljs-params">someProperty</span>')</span>;
</code></pre>
<p>You can also break on property read using <code>$dug</code>.</p>
<p>For more documentation and information on DebugUtils, be sure to check out the <a href="https://github.com/amasad/debug_utils">Github project</a>. Happy debugging!</p>
<p><strong>Edit</strong>: My EmpireJS talk on this subject</p>
<iframe width="560" height="315" src="//www.youtube.com/embed/rcjUR4icvoQ" frameborder="0" allowfullscreen></iframe>
]]></content:encoded>
            <author>amjad.masad@gmail.com (Amjad Masad)</author>
        </item>
        <item>
            <title><![CDATA[Building an In-Browser JavaScript VM and Debugger Using Generators]]></title>
            <pubDate>Mon, 06 Jan 2014 00:00:00 GMT</pubDate>
            <description><![CDATA[ ### tl;dr  I built a JavaScript VM and debugger in JavaScript. Checkout the example in the [demo app](http://debugjs.com/#example) and the [source code](https://github.com/amasad/debugjs). Read on fo...]]></description>
            <content:encoded><![CDATA[<h3 id="tl-dr">tl;dr</h3>
<p>I built a JavaScript VM and debugger in JavaScript. Checkout the example in the <a href="http://debugjs.com/#example">demo app</a> and the <a href="https://github.com/amasad/debugjs">source code</a>. Read on for a dive into the technical details.</p>
<p>Update: <a href="/2014/01/10/implementing-bret-victors-learnable-programming-has-never-been-easier/">I implemented one of the examples from Bret Victor&#39;s Learnable Programming</a> using debug.js.</p>
<h3 id="introduction">Introduction</h3>
<h4 id="motivation">Motivation</h4>
<p>For the past few years I&#39;ve been working on creating tools to help people learn programming on the web. I&#39;ve worked on <a href="http://repl.it">repl.it</a> and open sourced the underlying technology which powered a <a href="https://www.udacity.com/">few</a> <a href="http://www.codecademy.com/">learn</a> to <a href="http://www.learnstreet.com/">code</a> websites and until recently lead product engineering at Codecademy. Through all that, one thing I really wanted to see are the tools to make it possible to visualize code execution and step through code in the browser. To catch glimpse of what an ideal interactive learning environment would be you should check out <a href="http://worrydream.com/LearnableProgramming/">Learnable Programming</a> by Bret Victor.</p>
<p>In addition to the educational benefits of such a tool, if matured it could be also useful for code instrumentation, web IDEs, and creating a foundation for writing other VMs on top of JavaScript (having the pausable machine state let’s you not worry about the non-blocking environment).</p>
<p>Ever since I&#39;ve read about the <a href="http://wiki.ecmascript.org/doku.php?id=harmony:generators">ES6 Generators</a> proposal, I&#39;ve been toying with this idea in my head but it wasn&#39;t a real possibility until <a href="https://twitter.com/benjamn">Ben Newman’s</a> <a href="http://facebook.github.io/regenerator/">Regenerator</a> brought generators to the browser.</p>
<h4 id="goals">Goals</h4>
<ul>
<li>JS VM capable of running ES5 code</li>
<li>VM should be pausable on any instruction</li>
<li>Ability to create a feature complete JS debugger on top of the VM</li>
<li>Mainly targeting browsers but should work in Node.js for development</li>
</ul>
<h3 id="generators">Generators</h3>
<p><em>if you&#39;re familiar with generators, feel free to skip this section or read <a href="http://tobyho.com/2013/06/16/what-are-generators/">this</a> instead for a more comprehensive introduction</em></p>
<p>Generators are part of the ES6 proposals and is making it&#39;s way slowly into production environments. Generators gives us a new type of functions where we can step in and out of a function while sending  and receiving values to and from it.</p>
<p>The following example should illustrate the fundamentals of generators:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span>* <span class="hljs-title">genFn</span><span class="hljs-params">()</span></span> {
  var x = <span class="hljs-built_in">yield</span> <span class="hljs-number">2</span>;
  <span class="hljs-built_in">yield</span> x;
  <span class="hljs-keyword">return</span> <span class="hljs-string">'done'</span>;
}

var gen = genFn()
console.<span class="hljs-built_in">log</span>(gen.<span class="hljs-built_in">next</span>());  // {value: <span class="hljs-number">2</span>, done: <span class="hljs-literal">false</span>}
console.<span class="hljs-built_in">log</span>(gen.<span class="hljs-built_in">next</span>(<span class="hljs-number">1</span>)); // {value: <span class="hljs-number">1</span>, done: <span class="hljs-literal">false</span>}
console.<span class="hljs-built_in">log</span>(gen.<span class="hljs-built_in">next</span>());  // {value: <span class="hljs-string">"done"</span>, done: <span class="hljs-literal">true</span>}
</code></pre>
<p><em>Notice the * at the end of the <code>function</code> keyword, that&#39;s all you need to create a generator.</em></p>
<h3 id="overview">Overview</h3>
<p>Having the unique ability of suspending execution of a function and resuming at a later point in time, generators gives us the basic building block for creating a VM that can step through instructions and pause at any point. To achieve that, every function in the system must be transformed into a generator that yields to the machine before every instruction execution. This may sound similar to <a href="http://en.wikipedia.org/wiki/Continuation-passing_style">Continuation Passing Style</a> with a trampoline, however, the main difference is that the call stack information in CPS is held in the lexical scope whereas in this method we need to take full control of the call stack. I&#39;m not a compiler nor a PLT expert so I&#39;m not really sure if this method has a name or if it has been tried before, if you do please let me know.</p>
<p>We want the host JavaScript environment to take on as much of the responsibility of running code as possible. Beyond generator function transformation we have to do a few other things which I&#39;ll outline here and get into each later.</p>
<ul>
<li>Control the call stack</li>
<li>Handle errors and error propagation</li>
<li>Control timers in the system (setTimeout, setInterval etc)</li>
<li>Workaround native APIs that expect function arguments (callbacks and not generators)</li>
<li>Write a debugger module</li>
</ul>
<h3 id="code-transformation">Code Transformation</h3>
<p>In order to control the execution flow we need to yield back to the machine after each instruction execution. To do so, we take each instruction in our program and insert a <code>yield</code> expression before it. I chose to define an instruction (or a step) as a single JavaScript statement.</p>
<p>For example:</p>
<pre><code class="lang-javascript"><span class="hljs-attribute">var</span> foo = <span class="hljs-number">1</span>;
<span class="hljs-attribute">if</span> (bar === foo) {
  <span class="hljs-attribute">foo</span> = <span class="hljs-number">2</span>;
}
</code></pre>
<p> After the transformation:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span>* <span class="hljs-title">__top</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">yield</span> {step};
  <span class="hljs-keyword">var</span> foo = <span class="hljs-number">1</span>;
  <span class="hljs-keyword">yield</span> {step};
  <span class="hljs-keyword">if</span> (bar === foo) {
    <span class="hljs-keyword">yield</span> {step};
    foo = <span class="hljs-number">2</span>;
  }
}
</code></pre>
<p>In addition to the basic instruction transformation we need to add information about each function in our program that would be useful when building the debugger. We call this, a stack frame and it includes the following data about our function:</p>
<ul>
<li>name</li>
<li>filename</li>
<li>scope: an array of variable names and their occurrences in the function.</li>
<li>eval function: this gives access to the function&#39;s closure to do things like watch expressions and eval code in that scope.</li>
</ul>
<p>Finally, function calls are a bit trickier than regular instructions since we need to capture the call stack and play nicely with native and library function calls. On compile time, at the function call site, we don&#39;t know whether a function call is referencing a generator function (a function within our ecosystem) or a function object. If it was the former, we need to add it to our call stack and step into executing the function instructions, as for the latter we simply need to get a value out of it. We solve the issue by wrapping all function calls in a thunk and yield it back to the machine to make that decisions on runtime (where we have more information).</p>
<p>“Thunk” is a fancy word for something JavaScript programmers do all the time -- create a closure that delays the computation of a piece of code. To illustrate:</p>
<pre><code class="lang-javascript">foo()<span class="hljs-comment">;</span>
</code></pre>
<p>Becomes:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">yield</span> __thunk(<span class="hljs-function"><span class="hljs-keyword">function</span> *<span class="hljs-title">thunk</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> foo();
}, <span class="hljs-keyword">this</span>, <span class="hljs-built_in">arguments</span>);
</code></pre>
<p>A more complex call expression would also work:</p>
<pre><code class="lang-javascript">for (<span class="hljs-name">var</span> i = foo(), b = bar()<span class="hljs-comment">; i &lt; 50; i++);</span>
</code></pre>
<p>Becomes:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-keyword">yield</span> __thunk(<span class="hljs-function"><span class="hljs-keyword">function</span>* <span class="hljs-title">thunk</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> foo();
}, <span class="hljs-keyword">this</span>, <span class="hljs-built_in">arguments</span>), b = <span class="hljs-keyword">yield</span> __thunk(<span class="hljs-function"><span class="hljs-keyword">function</span>* <span class="hljs-title">thunk</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> bar();
}, <span class="hljs-keyword">this</span>, <span class="hljs-built_in">arguments</span>); i &lt; <span class="hljs-number">50</span>; i++);
</code></pre>
<p><code>this</code> and <code>arguments</code> are passed down so we can create the correct scope when invoking the thunk.</p>
<h3 id="vm">VM</h3>
<h4 id="stepping-and-the-call-stack">Stepping and The Call Stack</h4>
<p>Our machine&#39;s main responsibility is to invoke, push, and pop functions off the call stack. It starts out with a halted (or idle state) until we eval a string of code which is transformed and converted into a top-level generator. Then, we can call <code>step</code> on the machine and expect it to run the next instruction in our code via the generator <code>next()</code> method. If that instruction returns a thunk, we evaluate it and if it returns a generator we push it onto our call stack and any further steps will be invoked on it. When our current peek generator is done stepping we take the last value and pass it back into the next generator on our call stack. The passing is also done via the generator <code>.next</code> function which accepts an argument to be sent into the generator function.</p>
<h3 id="errors">Errors</h3>
<p>When invoking an instruction, there is a possibility it could throw an error. The way we deal with that is we try/catch every instruction invocation and if we get an error we pass it up the call stack incase one of the caller functions have try/catch statement waiting for us.</p>
<pre><code class="lang-javascript">Runner.prototype.$propError = function (e) {
  <span class="hljs-keyword">while</span> (<span class="hljs-keyword">this</span>.stack.length) {
    <span class="hljs-keyword">this</span>.gen = <span class="hljs-keyword">this</span>.stack.pop();
    <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">this</span>.gen.<span class="hljs-keyword">throw</span>(e);
      <span class="hljs-keyword">return</span>;
    } <span class="hljs-keyword">catch</span> (e2) {
      e = e2;
    }
  }
  <span class="hljs-keyword">throw</span> e;
};
</code></pre>
<h4 id="timers">Timers</h4>
<p>One of our goals is to be able to pause our machine at an point in time and for as much time as needed. Because of that we run into the problem of not being able to rely on the host JavaScript environment for controlling timers. e.g. we have a <code>setInterval</code> running with a second in between and we decided to pause the machine for 10 seconds, when we resume we shouldn&#39;t expect 10 back-to-back timers to trigger. The machine time should only be running when:</p>
<ol>
<li>We are executing instruction code.</li>
<li>We are in idle state (the call stack has unwinded and the machine is in a halted state).</li>
</ol>
<p>We use a priority queue to store our timers and have a tick method that checks if there are any timers that should fire at that point in time. We rely on the host <code>setImmediate</code> or <code>setTimeout(tick, 0)</code> to provide us with our tick function.</p>
<p>When a timer fires the machine simply triggers <code>timer</code> event and clients could react by running or stepping through the timer (thus creating a new call stack). This is very similar to JavaScript event loops but very specific to timers.</p>
<h4 id="native-apis">Native APIs</h4>
<p>We can&#39;t expect every API our code touches to understand how we do things using generators so the machine provides a way to wrap callbacks and yield them back to the machine to further step through them. However, a problem arises when we consider synchronous APIs that expect callbacks, for example <code>Array.forEach</code> will call the callback continuously until the iteration finishes and that&#39;s a problem because we expect to be able to pause any execution indefinitely. For that reason, we can&#39;t rely on the host environment native APIs to do the same thing. Luckily, this turns out not to be very hard to solve. All it took is taking the popular <a href="https://github.com/es-shims/es5-shim">es5-shim</a> library and running our transformation on it so it become generator friendly.</p>
<h4 id="events">Events</h4>
<p>Much like the the Native API problem, events expects event listeners made of functions, but this is a much simpler problem because this is an asynchronous API and all we have to do is wrap our listeners with a function wrapper that would trigger our machine whenever it&#39;s called.</p>
<h4 id="debugger">Debugger</h4>
<p>After creating the VM, writing the debugger was fun and relatively straightforward. The only issue I ran into is handling all the thunk garbage we have in our call stack because we treated them just like any function call to make the machine simpler.</p>
<p>Features:</p>
<ul>
<li>Breakpoints</li>
<li>Debugger statements</li>
<li>Step in, out, and over any statement</li>
<li>Get scope variables and values</li>
<li>Get call stack</li>
<li>Eval in scope: whenever you on a breakpoint you can evaluate in that scope</li>
</ul>
<p>Check it out <a href="http://debugjs.com">here</a>.</p>
<h4 id="current-status">Current status</h4>
<p>The project is still in early development stages. I’ve only been working on it for about two weeks. In terms of correctness, I’m sure the VM can run most of the ES5 spec. One thing that came to mind while writing this post is that getters and setters are definitely broken at the moment.</p>
<p>The VM is currently very slow, especially the code transformation bit but there are a few quick wins to be had there to get it to an OK speed.</p>
<p>I also realize that the generator transformation is just an intermediate step to the transformation that Regenerator does to be able to step in and out of functions freely. Therefore we could get rid of that step and transform directly to the state machine.</p>
]]></content:encoded>
            <author>amjad.masad@gmail.com (Amjad Masad)</author>
        </item>
        <item>
            <title><![CDATA[On VMs in JavaScript]]></title>
            <pubDate>Tue, 17 Jul 2012 00:00:00 GMT</pubDate>
            <description><![CDATA[ There are many challenges in implementing a language VM in JavaScript. Amongst those is the fact that your VM will be forced to live in a non-blocking environment, whereas most language interpreters ...]]></description>
            <content:encoded><![CDATA[<p>There are many challenges in implementing a language VM in JavaScript. Amongst those is the fact that your VM will be forced to live in a non-blocking environment, whereas most language interpreters are designed to be able to block in some cases. This forces JavaScript programs to be structured differently. Programs run shortly registering callbacks for events and yielding to the event loop that will dispatch the callback when the event is fired. While many enjoy this style of programming, there are others that think there is a better way:</p>
<ul>
<li><a href="http://tamejs.org/">TameJS</a></li>
<li><a href="http://www.neilmix.com/narrativejs/doc/index.html">Narrative JavaScript</a></li>
<li><a href="http://chumsley.org/jwacs/">jwacs</a>
and the list goes on...</li>
</ul>
<h3 id="in-the-vm">In the VM</h3>
<p>You maybe asking yourself what kind of asynchronous operations would an interpreter need to do in the first place. Good question! It&#39;s always good practice to put computationally heavy programs in Web Workers and that include VMs which makes interactions with the UI thread asynchronous, which for the most part, is ok, except to when it comes to user input. Most would expect it to be blocking. Also having the ability to pause and resume execution at any point in time would open the opportunity to create debugging tools like a stepping debugger.</p>
<p>One thing you can and many already do is <strong>design your VM with a yield state</strong>. But that doesn&#39;t really apply when implementing an X-to-JavaScript compiler or when compiling interpreters from other languages to JavaScript or when writing simple interpreters without really implementing a full blown VM.</p>
<h3 id="case-study-bf-interpreter">Case study: BF Interpreter</h3>
<p>For the following section I will use a <a href="http://en.wikipedia.org/wiki/Brainfuck">brainfuck</a> interpreter to illustrate the problem and part of the solution.</p>
<h4 id="bf-interpreter">BF Interpreter</h4>
<p>The function <code>bf</code> takes a string made of characters representing a BF program and runs it. You do not need to know what all the operations in the BF interpreter are but note that the input command <code>,</code> asks for user input.</p>
<pre><code><span class="hljs-comment">// Adapted from http://code.google.com/p/jslibs/wiki/JavascriptTips</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">bf</span> (<span class="hljs-params">code</span>) </span>{
  <span class="hljs-keyword">var</span> codeLength = code.length

    <span class="hljs-comment">// Code pointer</span>
    , cp = <span class="hljs-number">0</span>

    <span class="hljs-comment">// Data pointer</span>
    , dp = <span class="hljs-number">0</span>

    <span class="hljs-comment">// Tape.</span>
    , m = []

<span class="hljs-comment">// Loop start and end positions.</span>
    , loopIn = {}
    , loopOut = {}

<span class="hljs-comment">// Match [].</span>
    , stack = [];

  <span class="hljs-comment">// Register loop jumps</span>
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> cp = <span class="hljs-number">0</span>; cp &lt; codeLength; cp++) {
    <span class="hljs-keyword">if</span> (code[cp] == <span class="hljs-string">'['</span>)
      stack(cp);
    <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (code[cp] == <span class="hljs-string">']'</span>)
      loopOut[loopIn[cp] = stack()] = cp;
  }

<span class="hljs-comment">// Execute.</span>
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> cp = <span class="hljs-number">0</span>; cp &lt; codeLength; cp++) {
    <span class="hljs-keyword">switch</span>(code[cp]) {
      <span class="hljs-keyword">case</span> <span class="hljs-string">'&gt;'</span>:
        dp++;
        <span class="hljs-keyword">break</span>;
      <span class="hljs-keyword">case</span> <span class="hljs-string">'&lt;'</span>:
        dp--;
        <span class="hljs-keyword">break</span>;
      <span class="hljs-keyword">case</span> <span class="hljs-string">'+'</span>:
        m[dp] = ((m[dp]||<span class="hljs-number">0</span>)+<span class="hljs-number">1</span>)&amp;<span class="hljs-number">255</span>;
        <span class="hljs-keyword">break</span>;
      <span class="hljs-keyword">case</span> <span class="hljs-string">'-'</span>:
        m[dp] = ((m[dp]||<span class="hljs-number">0</span>)<span class="hljs-number">-1</span>)&amp;<span class="hljs-number">255</span>;
        <span class="hljs-keyword">break</span>;
      <span class="hljs-keyword">case</span> <span class="hljs-string">'.'</span>:
        <span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">String</span>.fromCharCode(m[dp]));
        <span class="hljs-keyword">break</span>;
      <span class="hljs-keyword">case</span> <span class="hljs-string">','</span>:
        m[dp] = prompt(<span class="hljs-string">'input'</span>).charCodeAt(<span class="hljs-number">0</span>)||<span class="hljs-number">0</span>;
        <span class="hljs-keyword">break</span>;
      <span class="hljs-keyword">case</span> <span class="hljs-string">'['</span>:
        m[dp]||(cp=loopOut[cp]);
        <span class="hljs-keyword">break</span>;
      <span class="hljs-keyword">case</span> <span class="hljs-string">']'</span>:
        cp = loopIn[cp]<span class="hljs-number">-1</span>;
        <span class="hljs-keyword">break</span>;
    }
  }
}
</code></pre><p>Now the above is a <strong>synchronous</strong> BF interpreter written in JavaScript and it uses <code>prompt</code> for input (<code>,</code>) which is the browser&#39;s native blocking stdin. Loading it in the main browser UI thread would work, however, running large BF programs would cause it to block and hang your tab or browser. Loading it in a Web Worker would not work either because Workers do <strong>not</strong> have access to the <code>window</code> obect.</p>
<h4 id="cps-ed-bf-interpreter">CPS&#39;ed BF interpreter</h4>
<p>We can try fixing the interpreter by making the input operation a non-blocking call that takes a callback to continue the program after input was recieved from the user from the UI thread, via the Web Worker message API. let us assume this has been already implemented for us and we can use: <code>console.input</code>.</p>
<p>You would quickly notice that having an asynchrounous operation is infectious and it would force us to restructure our program into a <a href="http://en.wikipedia.org/wiki/Continuation-passing_style">CPS</a> style.</p>
<p><em>Note that This could be further simplified but it&#39;s left to demonstrate the point.</em></p>
<pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">bf</span> (<span class="hljs-params">code</span>) </span>{
  <span class="hljs-keyword">var</span> codeLength = code.length
    , i = <span class="hljs-number">0</span>, cp = <span class="hljs-number">0</span>, dp = <span class="hljs-number">0</span>
    , loopIn = {}, loopOut = {}, m = {}
    , stack = [];

  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> cp = <span class="hljs-number">0</span>; cp &lt; codeLength ; cp++) {
    <span class="hljs-keyword">if</span> (code[cp] == <span class="hljs-string">'['</span>)
      stack.push(cp);
    <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (code[cp] == <span class="hljs-string">']'</span>)
      loopOut[loopIn[cp] = stack.pop()] = cp;
  }

  <span class="hljs-keyword">var</span> ops = {
    <span class="hljs-string">'&gt;'</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">cont</span>) </span>{
      dp++;
      cont();
    }
  , <span class="hljs-string">'&lt;'</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">cont</span>) </span>{
      dp--;
      cont();
    }
  , <span class="hljs-string">'+'</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">cont</span>) </span>{
      m[dp] = ((m[dp]||<span class="hljs-number">0</span>)+<span class="hljs-number">1</span>)&amp;<span class="hljs-number">255</span>;
      cont();
    }
  , <span class="hljs-string">'-'</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">cont</span>) </span>{
      m[dp] = ((m[dp]||<span class="hljs-number">0</span>)<span class="hljs-number">-1</span>)&amp;<span class="hljs-number">255</span>;
      cont();
    }
  , <span class="hljs-string">'.'</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">cont</span>) </span>{
      <span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">String</span>.fromCharCode(m[dp]));
      cont();
    }
  , <span class="hljs-string">','</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">cont</span>) </span>{
      <span class="hljs-built_in">console</span>.input(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">data</span>) </span>{
        m[dp] = data.charCodeAt(<span class="hljs-number">0</span>) || <span class="hljs-number">0</span>;
        cont();
      });
    }
  , <span class="hljs-string">'['</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">cont</span>) </span>{
      m[dp]||(cp=loopOut[cp]);
      cont();
    }
  , <span class="hljs-string">']'</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">cont</span>) </span>{
      cp = loopIn[cp]<span class="hljs-number">-1</span>;
      cont();
    }
  };

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">noop</span> (<span class="hljs-params"></span>) </span>{}

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">runNext</span> (<span class="hljs-params"></span>) </span>{
    cp++;
    <span class="hljs-keyword">if</span> (cp &lt; codeLength) {
      (ops[code[cp]] || noop)(runNext);
    }
  }
  cp = <span class="hljs-number">-1</span>;
  runNext();
}
</code></pre><p>Notice how every function in the system receives a callback function which is responsible for continuing the program. The callback maybe called with values that would&#39;ve rather been return values. In our case, there exist no need for return values because state is encapsulated within the <code>bf</code> function closure.</p>
<p>By doing so <strong>We eliminated the need for a JavaScript runtime call stack</strong>, as each function would be responsible for continuing the execution of the program. Which means each function has the power and ability to stop the execution (maybe wait for an event to happen) and continue at a later time. Which I think is freeing.</p>
<h4 id="blow-it-up">Blow it up</h4>
<p>Even-though we don&#39;t need an actual call stack anymore because every function call in our program is the last statement in it&#39;s caller function that would be responsible for continuing it&#39;s program after it finishes executing. However we are still bound to the runtime&#39;s call stack, that would be exhausted as soon as we try to run a non-trivial BF program.</p>
<p>Luckily in functional programming there is a technique called trampolining that would help minimize the call stack size needed to run programs written in CPS. It works by having a loop that is responsible for calling the program&#39;s functions that would in turn return a continuation function to be executed by the same loop.</p>
<pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">bf</span> (<span class="hljs-params">code</span>) </span>{
  <span class="hljs-keyword">var</span> codeLength = code.length
    , i = <span class="hljs-number">0</span>, cp = <span class="hljs-number">0</span>, dp = <span class="hljs-number">0</span>
    , loopIn = {}, loopOut = {}, m = {}
    , stack = [];

  <span class="hljs-keyword">for</span> (cp = <span class="hljs-number">0</span>; cp &lt; codeLength ; cp++)
    <span class="hljs-keyword">if</span> (code[cp] == <span class="hljs-string">'['</span>) stack.push(cp);
    <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (code[cp] == <span class="hljs-string">']'</span>) loopOut[loopIn[cp] = stack.pop()] = cp;

  <span class="hljs-keyword">var</span> ops = {
    <span class="hljs-string">'&gt;'</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
      dp++;
      <span class="hljs-keyword">return</span> runNext;
    }
  , <span class="hljs-string">'&lt;'</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
      dp--;
      <span class="hljs-keyword">return</span> runNext;
    }
  , <span class="hljs-string">'+'</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
      m[dp] = ((m[dp]||<span class="hljs-number">0</span>)+<span class="hljs-number">1</span>)&amp;<span class="hljs-number">255</span>;
      <span class="hljs-keyword">return</span> runNext;
    }
  , <span class="hljs-string">'-'</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
      m[dp] = ((m[dp]||<span class="hljs-number">0</span>)<span class="hljs-number">-1</span>)&amp;<span class="hljs-number">255</span>;
      <span class="hljs-keyword">return</span> runNext;
    }
  , <span class="hljs-string">'.'</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
      <span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">String</span>.fromCharCode(m[dp]));
      <span class="hljs-keyword">return</span> runNext;
    }
  , <span class="hljs-string">','</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
      <span class="hljs-keyword">return</span> <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
        <span class="hljs-built_in">console</span>.input(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">data</span>) </span>{
          m[dp] = data.charCodeAt(<span class="hljs-number">0</span>) || <span class="hljs-number">0</span>;
          run(runNext);
        });
      };
    }
  , <span class="hljs-string">'['</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
      m[dp]||(cp=loopOut[cp]);
      <span class="hljs-keyword">return</span> runNext;
    }
  , <span class="hljs-string">']'</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
      cp = loopIn[cp]<span class="hljs-number">-1</span>;
      <span class="hljs-keyword">return</span> runNext;
    }
  };

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">noop</span> (<span class="hljs-params"></span>) </span>{}

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">runNext</span> (<span class="hljs-params"></span>) </span>{
    cp++;
    <span class="hljs-keyword">if</span> (cp &lt; codeLength)
      <span class="hljs-keyword">return</span> (ops[code[cp]] || noop)();
  }

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">run</span> (<span class="hljs-params">cont</span>) </span>{
    <span class="hljs-comment">// Trampoline.</span>
    <span class="hljs-keyword">while</span> (<span class="hljs-keyword">typeof</span> cont === <span class="hljs-string">'function'</span>) {
      cont = cont();
    }
  }

  cp = <span class="hljs-number">-1</span>;
  run(runNext);
}
</code></pre><h4 id="a-glimpse-into-the-future">A glimpse into the future</h4>
<p>Things should not be this hard. JavaScript must grow as a language to allow constructs that makes it easier to write asynchronous programs. In addition to the web finally realizing the dream of being the application platform, JavaScript also plays a strong role in evented-io server programming which had proven to be quite efficient.</p>
<p>Let us take a look at using <a href="http://wiki.ecmascript.org/doku.php?id=harmony:generators">generators</a> to emulate coroutines that will land in the next version of JavaScript, ES Harmony. The following example is written using the excellent <a href="http://taskjs.org/">task.js</a> library:</p>
<pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">bf</span> (<span class="hljs-params">code</span>) </span>{

  <span class="hljs-comment">// Create a task that could yield.</span>
  task.spawn(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">var</span> codeLength = code.length
      , i = <span class="hljs-number">0</span>, cp = <span class="hljs-number">0</span>, dp = <span class="hljs-number">0</span>
      , loopIn = {}, loopOut = {}, m = {}
      , stack = [];

    <span class="hljs-keyword">for</span> ( <span class="hljs-keyword">var</span> cp = <span class="hljs-number">0</span>; cp &lt; codeLength ; cp++ )
      <span class="hljs-keyword">if</span> ( code[cp] == <span class="hljs-string">'['</span> )
        stack.push(cp);
      <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> ( code[cp] == <span class="hljs-string">']'</span> )
        loopOut[loopIn[cp] = stack.pop()] = cp;

    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> cp = <span class="hljs-number">0</span>; cp &lt; codeLength &amp;&amp; i &lt; <span class="hljs-number">100000</span>; cp++, i++) {
      <span class="hljs-keyword">switch</span>(code[cp]) {
        <span class="hljs-keyword">case</span> <span class="hljs-string">'&gt;'</span>:
          dp++;
          <span class="hljs-keyword">break</span>;
        <span class="hljs-keyword">case</span> <span class="hljs-string">'&lt;'</span>:
          dp--;
          <span class="hljs-keyword">break</span>;
        <span class="hljs-keyword">case</span> <span class="hljs-string">'+'</span>:
          m[dp] = ((m[dp]||<span class="hljs-number">0</span>)+<span class="hljs-number">1</span>)&amp;<span class="hljs-number">255</span>;
          <span class="hljs-keyword">break</span>;
        <span class="hljs-keyword">case</span> <span class="hljs-string">'-'</span>:
          m[dp] = ((m[dp]||<span class="hljs-number">0</span>)<span class="hljs-number">-1</span>)&amp;<span class="hljs-number">255</span>;
          <span class="hljs-keyword">break</span>;
        <span class="hljs-keyword">case</span> <span class="hljs-string">'.'</span>:
          <span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">String</span>.fromCharCode(m[dp]));
          <span class="hljs-keyword">break</span>;

        <span class="hljs-comment">// Yield to the event loop until we get the user input.</span>
        <span class="hljs-keyword">case</span> <span class="hljs-string">','</span>:
          m[dp] = <span class="hljs-keyword">yield</span> <span class="hljs-built_in">console</span>.input();
          <span class="hljs-keyword">break</span>;
        <span class="hljs-keyword">case</span> <span class="hljs-string">'['</span>:
          m[dp]||(cp=loopOut[cp]);
          <span class="hljs-keyword">break</span>;
        <span class="hljs-keyword">case</span> <span class="hljs-string">']'</span>:
          cp = loopIn[cp]<span class="hljs-number">-1</span>;
          <span class="hljs-keyword">break</span>;
      }
    }
 });
}
</code></pre><p>What&#39;s more, ES Harmony will also include tail call optimization.</p>
<h3 id="a-shameless-hack">A Shameless Hack</h3>
<p>To get input on the emscripten compiled languages on our <a href="http://repl.it">repl.it</a> project we considered using a CPS code transformer like the above-mentioned list but the approach failed for the following reasons:</p>
<ol>
<li>Compiling language interpreters to JS using <a href="https://github.com/kripken/emscripten/wiki">emscripten</a> generates <a href="https://raw.github.com/replit/empythoned/master/dist/python.opt.js">lots of JavaScript</a> which when ran against these compilers takes forever.</li>
<li>JavaScript is not <a href="http://en.wikipedia.org/wiki/Tail_call">tail call optimized</a>; and this is bad because compiling to CPS means functions would be used for control flow, a whole lot of them. However I think some transformers do use clever tricks to minimize call stack.</li>
<li>Performance hit which is for the most part from the cost of creating and invoking a lot of functions.</li>
<li>Adding an additional compile step makes it even harder to debug.</li>
</ol>
<p>So we took the easy way out and hacked the hell out of it. After thinking for a while about the problem of what in essence is resource sharing across threads which is prohibited in browsers for the added complexity and the security concerns of the web. I had a crazy idea of using the Web SQL Database to share data between the Worker and the UI thread since it has a synchronous worker API. While I&#39;m sure this hack doesn&#39;t make threads share memory but is fast enough for stdin. The busy loop count (100000000 in the code below) is tuned and maybe tuned further to get faster results.</p>
<p>When the language interpreter in a Web Worker hits an input operation it will stop execution, ask the main thread for input via a message, and busy loop while polling for changes in a Web Database table:</p>
<pre><code><span class="hljs-keyword">var</span> DB = <span class="hljs-keyword">self</span>.openDatabaseSync(<span class="hljs-string">'replit_input'</span>, <span class="hljs-string">'1.0'</span>, <span class="hljs-string">'Emscripted input'</span>, <span class="hljs-number">1024</span>);
<span class="hljs-keyword">var</span> input = <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">()</span> </span>{
  <span class="hljs-keyword">self</span>.postMessage(<span class="hljs-string">'stdin'</span>);
  <span class="hljs-keyword">var</span> t = <span class="hljs-keyword">null</span>;
  DB.transaction(<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(tx)</span> </span>{t=tx});
  <span class="hljs-keyword">var</span> i, res;
  <span class="hljs-keyword">while</span> (!(res = t.executeSql(<span class="hljs-string">'SELECT * FROM input'</span>).rows).length) {
    <span class="hljs-keyword">for</span> (i = <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">100000000</span>; i++);
  }
  t.executeSql(<span class="hljs-string">'DELETE FROM input'</span>);
  <span class="hljs-keyword">return</span> res.item(<span class="hljs-number">0</span>).text;
};
</code></pre><p>And in the UI thread:</p>
<pre><code>worker.addEventListener(<span class="hljs-string">'message'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">e</span>) </span>{
  <span class="hljs-keyword">if</span> (e.data === <span class="hljs-string">'stdin'</span>) {
    <span class="hljs-built_in">console</span>.input(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">data</span>) </span>{
      DB.transaction(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
        tx.executeSql(<span class="hljs-string">'INSERT INTO input (text) VALUES ('</span> + data + <span class="hljs-string">')'</span>, []);
      });
    });
  } <span class="hljs-keyword">else</span> {
    <span class="hljs-comment">// Do other stuff</span>
  }
}, <span class="hljs-literal">false</span>);
</code></pre><p>The Web SQL Database spec is deprecated for the IndexedDB which has not fully landed in browsers yet but this approach, in theory, should work with it.</p>
<h3 id="why-all-this-">Why all this?</h3>
<p>I ran into these issues during my work on <a href="http://repl.it">repl.it</a> last year. And my recent on and off work on allowing debugging JavaScript in the browser at <a href="http://codecademy.com">codecademy</a>.</p>
]]></content:encoded>
            <author>amjad.masad@gmail.com (Amjad Masad)</author>
        </item>
    </channel>
</rss>