Skip to content

YJIT: Building a New JIT Compiler Inside CRuby

The 1980s and 1990s saw the genesis of Perl, Ruby, Python, PHP and JavaScript: interpreted, dynamically-typed programming languages which favored ease of use and flexibility over performance. In many ways, these programming languages are a product of the surrounding context. The 90s were the peak of the dot-com hype, and CPU clock speeds were still doubling roughly every 18 months. It looked like the growth was never going to end. You didn’t really have to try to make your software run fast, because computers were just going to get faster, and the problem would take care of itself. Today, things are a little different. We’re reaching the limit of current fabrication technologies, we can’t rely on single-core performance increases to solve our performance problems, and because of mobile devices and environmental concerns, we’re starting to realize that energy efficiency matters.

Last year, during the pandemic, I took a job at Shopify, a company that has a massive server infrastructure powered by Ruby on Rails. I joined a team with multiple software engineers working on improving the performance of Ruby code in a variety of ways, ranging from optimizing the CRuby interpreter and its garbage collector, to the implementation of TruffleRuby, an alternative Ruby implementation. Since then, I’ve been working with a small team of skilled engineers on YJIT, a new JIT compiler inside CRuby.

This project is important to Shopify and Ruby developers worldwide because speed is an underrated feature. There is already a JIT compiler inside CRuby, known as MJIT, which has been in the works for 3 years, and while it has delivered speedups on smaller benchmarks, it has, so far, been less successful at delivering real-world speedups on widely used Ruby applications including Rails. With YJIT, we take a data-driven approach, and focus specifically on performance hotspots of larger applications such as Rails and Shopify Core (Shopify’s main Rails monolith).

YJIT is an attempt to gradually build a JIT compiler inside CRuby such that more and more of the code is executed by the JIT, which will eventually replace the interpreter for most of the execution. Our compiler is based on Basic Block Versioning (BBV), a JIT compiler architecture I started developing during my PhD. I’ve given a talk about YJIT in March of this year at MoreVMs 2021 workshop if you’re curious to hear more about the approach we’re taking.

I don’t want to oversell YJIT. Our results have significantly improved since the MoreVMs talk, but are still modest. We’re very much at the early stages of this project and there are known bugs in our implementation. That being said, according to our benchmarks, we’ve been able to achieve speedups over the CRuby interpreter of 7% on railsbench, 19% on liquid template rendering, and 19% on activerecord. YJIT also delivers very fast warm up. It reaches near-peak performance after a single iteration of any benchmark, and performs at least as well as the interpreter on every benchmark, even on the first iteration.

Building YJIT inside CRuby comes with a number of limitations. It means that our JIT compiler has to be written in C, and that we have to live with design decisions in the CRuby codebase that were not made with a high performance JIT compiler in mind. However, it has the key advantage that YJIT is able to maintain almost 100% compatibility. We are able to pass the CRuby test suite, comprising about 30,000 tests, and we have also been able to pass all of the tests of the Shopify Core CI, a codebase that comprises over 3 million lines of code and depends (directly and indirectly) on over 500 Ruby gems, as well as all the tests in the CI for GitHub’s backend.

We believe that the BBV architecture that powers YJIT offers some key advantages when it comes to compiling dynamically-typed code, and that having end-to-end control over the full code generation pipeline will allow us to go farther than what is possible with the current architecture of MJIT, which is based on GCC. Notably, YJIT can quickly specialize code based on type information and patch code at run time based on the run-time behavior of programs.

Currently, only about 50% of instructions in railsbench are executed by YJIT, and the rest run in the interpreter, meaning that there is still a lot we can do to improve upon our current results. There is a clear path forward and we believe YJIT can deliver much better performance than it does now. However, as part of building YJIT, we’ve had to dig through the implementation of CRuby so we could understand it in detail. In doing so, it’s become obvious that one of the main performance challenges in implementing a fast JIT compiler in CRuby, is that key elements of the architecture are optimized with an interpreter in mind, and not a JIT compiler.

For instance, in CRuby every object instance variable read or write requires multiple pointer indirections and dynamic checks. In order to read an instance variable (ivar) from a Ruby object, one has to:

  1. Check that the receiver is a not an immediate value
  2. Check that the receiver is not Qnil
  3. Check that the receiver is a T_OBJECT
  4. Check that the object class matches our inline cache
  5. Read the serial number from the class (extra pointer indirection, memory access)
  6. Check whether the object stores its ivars internally or on an external table
  7. Potentially: read the pointer to the external table (extra memory access)
  8. Potentially: check if the ivar index is within the bounds of the external table
  9. Read the ivar from the object or external table

Note that at the moment, only 3 instance variable slots can be stored directly on the object itself, so instance variables are almost always on an external table in the vast majority of accesses.

As you can imagine, even though some of these checks can sometimes be optimized away, generating efficient machine code for instance variable accesses in CRuby is very difficult. It doesn’t have to be this way. This problem was solved by Self, the successor of Smalltalk, in the early 1990s. Self used what they call “maps”, but nowadays are typically referred to as object shapes (see Section 3 of An Efficient Implementation of SELF). This is tested and proven technology, used by Chrome’s V8 , Firefox’s SpiderMonkey, and TruffleRuby. If you are curious, this excellent blog post by Mathias Bynens and this great talk by Benedikt Meurer explain the concept of object shapes and shape trees in more details.

# Optimized ivar reads can be as short as three x86 instructions
# ebx = pointer to the object
cmp [ebx + <object shape offset>], <cached object shape>
jne <inline cache miss>
mov eax,[ebx, <cached ivar offset>] # load the ivar value

Thanks to object shapes, V8, SpiderMonkey and TruffleRuby are able to implement instance variable reads in as little as one single dynamic check, giving them an enormous performance advantage. We believe that with a coordinated effort that involves the Ruby Core developers, key technologies such as this could be implemented inside CRuby, and would benefit MJIT, YJIT, and any other future attempts to implement a JIT inside CRuby, and this without significantly impacting the performance of the interpreter.

Matz has stated in his recent talk at Euruko 2021 that Ruby would remain conservative with language additions in the near future. We believe that this is a wise decision as rapid language changes can make it difficult for JIT implementations to get off the ground and stay up to date. It makes some sense, in our opinion, for Ruby to focus on internal changes that will make the language more robust and deliver competitive performance in the future.

I believe that, through incremental, targeted changes, CRuby can be gradually re-engineered so that it can eventually have a true high-performance JIT compiler. Doing so must necessarily involve both JIT compiler experts and the Ruby Core developers. One key area of potential improvement would be the inclusion of object shapes. There are other things that could help us, such as rewriting some C methods in pure Ruby, such as Array#each and Fixnum#times, so that JIT compilers can inline through them. I may expand on such things in a future blog post. What would also be greatly helpful to JIT implementers is to have some commitment to stabilizing the internal Ruby bytecode format, or at least, to not add extra complexity and special cases to existing bytecode instructions. Currently, CRuby implements 11 kinds of method dispatch, which, as you can imagine, makes optimization and inlining very challenging.

If you’re interested in contributing or simply trying YJIT, it is available on GitHub under the same license as CRuby. The caveat of course is that we are at an early stage in this project and it’s very possible that you could run into bugs, or that you may not find the current performance particularly impressive. If you do want to help, YJIT could use more testing. Tracking down small regression tests for bugs is very valuable to us. We could also use more, larger benchmarks that better reflect real-world Ruby usage.

Investing is a Social Phenomenon

I first started trading on the stock market back in 2016. I had been curious about stock trading before that, but up until that point, I did what most people my age did, which is to simply put money into a regular savings account without really thinking about it. Things changed when I took a job at Apple in Silicon Valley. Part of the compensation was in Apple stock, and so, my new employer opened a stock brokerage account in my name where the shares would be deposited every six months. All of a sudden, I had access to a website where I could log in and place trades, and a whole new world was opened to me. I could own a small piece of some the greatest companies in the world, and that seemed really exciting, but which ones should I buy, and how much? What strategy should I use? I did what any responsible adult would do, and turned to YouTube and Reddit to look for answers.

This probably sounds laughable to many of you. I’m sure it would sound laughable to most Wall Street professionals, but there’s a lot of valuable information out there on YouTube, Reddit and other social media platforms. The key is knowing how to filter out valuable insight from terrible advice. Furthermore, investing fundamentally a social phenomenon, and as the GameStop saga made clear, social media is changing the game. Suddenly, ordinary folks with a computer or cellphone have access to an incredible amount of information, and huge online communities where they can exchange ideas. This is levelling the playing field to some extent.

That’s not to say that there isn’t anything dodgy happening on these platforms. I follow multiple YouTubers who post videos about stocks, and I noticed something both interesting and frightening. A YouTuber I won’t name, with over 600,000 followers, would often post videos where he would praise some specific stock. Often these stocks had relatively small market caps, about one billion dollars. Without fail, in the day following his videos being posted, the price of the stock discussed the day before would raise by something between 10 and 30%. This guy, simply by having a large online following, could easily manipulate the market in real time. The potential for abuse there is obviously enormous. Sven Carlin, another YouTuber I follow, revealed that he and many others had been offered money to promote certain stocks. This kind of scam is nothing new, I’m sure that Wall Street stock analysts have been paid to promote stocks for as long as there have been stock analysts, but again, social media is changing the game. People you assume to be trustworthy regular folks just sharing their personal opinion might actually be paid shills, it’s just much harder to tell because they’re not wearing suits.

Why is it that the stock price of some companies, like Amazon or Tesla, seems to rise exponentially? It’s because investing is fundamentally a social phenomenon. Investing is about trust, and the stock price of a company reflects our collective belief in the future potential of that company to succeed and grow. For many years, the stock price of Amazon didn’t move very much. People questioned their ability to succeed, and the fact that they weren’t profitable, but some time around 2010, that view shifted very rapidly, as if some threshold had been reached. The idea that Amazon was going to succeed, that it was an unstoppable behemoth, became the dominant one seemingly overnight, and from that point on, the price of its stock never stopped rising. The same thing seems to be happening with Tesla. The company’s stock price has risen about 700% during 2020, and I don’t think that a rapid fundamental shift in the underlying business explains that. Rather, I think the rapid fundamental shift has been in the public perception of the company’s ability to deliver on its promises. That shift has been caused, in large part, by a large online community of unrelenting fans praising the company on social media. With social media, anyone can have a voice, it becomes possible for individuals to shift collective beliefs, and in doing so, we can make companies succeed or fail, and to some extent, reshape the future.

Investing is, or should be, about allocating capital to ideas you believe in, and it can be a beautiful thing, a force for change. Back in 2016, I started investing in multiple companies in the renewable energy space. I chose to do that because I was part of a growing online community of investors that believe in the potential of renewable energy, and its necessity for a better future. What I’ve been seeing, since then, is that as Tesla succeeds, more and more capital is flowing away from oil stocks and into renewable energy stocks. Starting in December 2019, before everyone was broadly aware of the pandemic, the price of oil giant Exxon Mobil took a sharp drop, while the price of Tesla started increasing steeply. Tesla has shown that renewable energy companies can succeed, and the rising tide lifts all boats. There’s more to it than just the stock price going up though. Like I said, the stock price, or more accurately, the total valuation of a company, reflects our collective belief that a company can succeed.

When a company’s stock price goes up, it suddenly becomes very easy for that company to raise money by selling more shares. This means there’s never been a better time to start a renewable energy company, because it’s easy to raise money to make that company grow. In some ways, it’s a self-fulfilling prophecy. Because we believe that green energy stocks can succeed, people buy the stock and their stock price goes up. Because people are buying green energy stocks, these companies can raise money easily. Since they can raise money easily, it’s much easier for them to grow, and to succeed, which also leads to a higher stock price. In many ways, our collective belief that these companies can succeed is making it possible for them to succeed. Are electric vehicle and green energy stocks in a bubble? Maybe, but it shouldn’t matter. Among these companies, those with competent management teams have already taken advantage of the current climate to raise money, and give themselves enough runway, even if there is a temporary pullback. Some of these companies will undoubtedly succeed, and the market will reward them for it. Don’t believe me, just watch.

On Insurmountable Technical Obstacles

John Carmack gave a great talk in which he explains why, before spending time working on an idea, he spends time trying to poke holes into it. Sometimes, it’s easy to get overly excited about an idea and get carried away. However, it could turn out that this idea has some fatal flaw, and if that’s the case, it’s probably be best if we can find that fatal flaw early, before spending hours, days or even weeks and months trying to implement a solution that was ultimately doomed to fail. There is wisdom in examining your ideas with an adversarial lens.

On the flip side, sometimes you have a problem that you need to solve, and you know it should be possible to solve it, because there’s no fundamental reason why the problem can’t be solved. I would say it’s been my experience that many people are often too quick to say that something can’t be done and dismiss all possible solutions you might suggest without doing due diligence. There’s often someone who will give you 100 reasons why your idea can’t work, and often, these people just lack imagination.

One example that has been on my mind recently is that of electric cars. Multiple jurisdictions have set the ambitious goal of completely ban the sale of gasoline-powered cars by 2035. Many Electric Vehicles (EV) advocates including myself believe that electric vehicles make up be the majority of new cars sold by 2030. Yet if you read discussions online, some vocal individuals will tell you that this is impossible. They will give you many reasons why electric vehicles can’t succeed, including range, a higher price tag, and that people living in apartments have nowhere to charge their vehicles. I would say that these people clearly lack imagination, and they’re failing to understand that reality is not static, it evolves over time as we adapt the world to our needs.

As technology progresses, the range and charging speed of electric vehicles keeps improving. As adoption increases, the price tag keeps coming down, and the amount of investment into EVs increases as well. I don’t live in a house, so I don’t have a garage, but at the last meeting of my condo association, the issue of installing EV chargers was brought up. This year, it should be possible for everyone who wants a charger installed to pay to add one at their parking spot. What about people who have to park their car on the street, you ask? You couldn’t possibly put a charger at every parking spot? Well, what if you could? Siemens is working on converting lamp posts into EV chargers. If you thought that charging on the street was an insurmountable technical obstacle, I say you lack imagination.

In 2020, Norway became the first country in which EVs took the majority of the new car market, with 54% of new vehicles sold being electric. You can argue that it’s easy for them, because they are wealthier than the rest of the world, but the reality is that electric vehicles are already coming down in price. There’s now a lot of competition, and Tesla has reiterated plans to produce a 25,000$ EV within a few years, with mass production inevitably bringing down costs.

The bottom line is, if there’s a problem that is really worth solving, trying to poke holes into potential solutions so you can dismiss them as quickly as possible isn’t always the right approach. You should do due diligence and give each potential solution a fair assessment, because you could also be shooting down ideas that would actually work. You should also ask yourself how you might actually go about overcoming the difficult obstacles that seem stand in the way, because some seemingly difficult obstacles might not turn out to be real issues in practice. The challenge to bring that idea into reality then becomes how to find a feasible path to your goal, and how to optimize and shorten that path as much as possible. Envisioning that path takes patience and some measure of imagination.

Combatting Pessimism: 3 Keys to Innovation

I strongly believe that in order to innovate, it’s important to be able to play with ideas. When you’re attacking a problem, it’s useful to be able to brainstorm, come up with multiple alternative solutions, and weigh the pros and cons. It’s also useful, in order to weigh the pros and cons, to try and imagine how a hypothetical solution can be integrated into an existing system, or how it could be extended, and what possible problems might arise.

It’s also very hard to innovate, to do something really new. Let’s face it, the total world population close to reaching almost 8 billion people. In every field, there is competition on all sides. Whatever you’re working on, there are likely other people working on it as well. Maybe someone else has already tried what you’re thinking of doing. It’s hard to stay relevant. If we just think about movie storylines, it almost seems as though every theme has been explored, and we’re just being fed the same clichés over and over again. Why even bother?

You Can Do It Better

I think the first thing to remember is that while a lot of ideas have already been thought of, many of them haven’t really been implemented properly. There are a lot of ideas that have been explored before, but poorly implemented. Coming up with an idea is the easy part, good execution is much harder. Most people give up without even trying. Some give up after they reach the first real technical obstacle. If you truly believe in the potential of an idea, you can separate yourself from the pack by going farther than the others who previously gave up.

Back in 2002, young Elon Musk founded SpaceX, with the goal of perfecting reusable rockets and sending people to Mars. Many people laughed at him. He had made a few millions with Paypal, but only an arrogant and narcissistic Silicon Valley entrepreneur could possibly imagine that he could launch a rocket company and take on established players like Boeing and Lockheed Martin. Yet, here we are, 18 years later, SpaceX has perfected reusable rocket boosters that can land themselves, they’ve sent astronauts to the ISS, they own most of the satellite launch market, and they’re now working on a fully reusable rocket.

SpaceX weren’t the first to work on reusable rockets. The idea wasn’t remotely new. The earliest concepts date back to the 1960s and there were many abandoned or failed projects. The competition was out there. There were a few multi-billion dollar companies already building rockets. If you’d asked me back in 2002, I would probably have said that Elon Musk had near-zero chance of succeeding. How did SpaceX manage to win? Probably, in part, because the existing players were overly comfortable. They had been fed secure government funding for decades. Why try to reinvent rockets when you can just keep doing the same thing and charge several hundreds of millions of dollars per launch? SpaceX won by executing an innovative vision to reduce cost with unwavering discipline. They went farther than everyone else, and built something much better.

On a smaller scale, if you’re an app developer, for example, you might be able to innovate over your competition by building an app with a simpler or more intuitive user interface. Maybe your app does nothing more than the others in terms of functionality, but it’s much easier to use. Your UI doesn’t require a user manual, users can figure out what to do quickly, and you reduce friction in a way that leads people to adopt your software.

Context Changes

The second thing you should know about ideas and innovation is that the world is always changing. It’s not the same place that it was 30, 20 or even 5 years ago. That makes it worthwhile to re-explore old ideas and adapt them to the modern context. In fact, there is this commonly known concept of the right idea at the wrong time.

There is a great documentary on a company called General Magic, who tried to build a smartphone with a touch screen too soon, before the technology was ready, and with poor, unfocused execution. There is also the story of the Apple Newton, which was also a flop. Many people knew that there was a clear future for Personal Digital Assistants (PDAs), but believing wasn’t enough, to make an idea come true, you need both good execution and an appropriate context.

Context is always changing. Sometimes very rapidly. Hardware becomes cheaper and better. The internet of 2020 is not the same as the internet of 1998 or even that of 2015. The people of today are different from the people of 10 or 20 years ago. You yourself are also changing and learning new things. Sometimes it’s worth re-examining old ideas. It’s not because others tried and failed that something is inherently impossible. Maybe they didn’t have the right skillset. Maybe they just weren’t in the right time, place or mindset.

Iterative Refinement

If there’s one thing you should believe in, as a software developer or as an engineer, it’s in the tremendous power of iterative refinement. You should believe in your own ability to learn from mistakes, be they your own mistakes or those of others, and refine a concept over time. By testing a machine again and again, you can identify flaws, and eliminate them, one at a time. You can go from a system that is broken and unusable to one that is fast and reliable. You don’t have to be fast, you don’t have to burn yourself out, you just need to keep at it.

SpaceX needed many attempts to figure out their rocket landing technology.

Sometimes it feels like we take two steps forward and one step back. I think that in the software industry, it helps to spend time building a solid suite of tests to avoid regressions. The most important ingredient though, in order to keep refining a solution, is strong belief in the final vision that we are ultimately trying to reach.

Conclusion

The most important strength that you have is your belief in your own ability to learn and succeed. You also need to be able to filter out good ideas from bad ones, and to judge whether the context is right or not. Sometimes though, you also have to find a way to quiet your inner critic, the pessimistic voice inside yourself that is deeply afraid of failure. It’s easy to come up with 1000 reasons why some idea might fail, but you’ll never know if you don’t give it a proper shot, and the best way to learn is by doing.

With the current ongoing pandemic, it’s very easy to be pessimistic right now. We’re lonely, isolated, and it’s easy to despair, to believe that the world is going to shit. That we’ll never leave this behind. However, multiple vaccines are completing human trials with positive results. Tens of millions of doses have already been fabricated, with billions more to be produced in 2021. Vaccination is already underway in some countries, and set to begin in the US in about two weeks, and in Canada starting in January. It might feel hopeless right now, but there is light at the end of the tunnel. I choose to believe in human ingenuity.

The Need for Stable Foundations in Software Development

My employer was kind enough to provide me with a top of the line MacBook Pro. It’s a beautiful machine with 6 CPU cores, 32GB of RAM and a 4K display, the most powerful laptop I’ve ever owned and a valuable tool in working from home. However, unfortunately, the slick machine suffers from a number of software problems.

For one, you can charge it using any of the 4 USB-C ports, but you really should only ever charge it from the right side. Another issue I frequently run into is that I have an external monitor, and despite configuring this as my primary display, the dock will randomly jump back to the MacBook’s monitor, until I go into the settings and move the dock to the right, and to the bottom again, at which point it goes back to the external monitor, until the next time it decides to randomly jump ship. A third issue is that whenever I reboot, it stays stuck early in the boot process, displaying the white Apple logo, and does nothing. It doesn’t complete the boot process until I unplug my USB-C devices. There are more problems, I could go on.

Apple isn’t the only one with these kinds of quality assurance problems. I recently installed Windows 8 on an older desktop computer I wanted to give to my mother (she unfortunately couldn’t see herself using Linux).  The first thing I did after installing the new OS was to try and run Windows Update. However, it didn’t work, and I was appalled to find that on this version of the OS, Windows Update is broken out of the box. I learned that there was a patch to fix the issue, but the patch didn’t work, it displayed a progress bar that remained perpetually frozen. Online searches revealed that in order to get the patch to work, I had to unplug the ethernet cable.

Why is it that we live in a world riddled with bugs? I think there are a few reasons for this. No doubt, part of the issue is that our competitive capitalist economy makes major software and hardware vendors want to move at breakneck speeds. Technological progress doesn’t nearly justify a new generation of smartphones being released each year, but, fuck the environment, a new product needs to be released in order to maintain interest and keep sales numbers high. We move fast, and in the process, we break things.

I’ve been a user of Ubuntu Linux for over 10 years now. I chose this distribution because, at the time, it was the most popular, and that made it easy to find software, as well as online help if anything ever went wrong. Originally, when I discovered Ubuntu, it used the GNOME desktop, and things worked fairly seamlessly. However, around 2011, Ubuntu began shipping with a different user interface which they called Unity. This new user interface was riddled with bugs, and the reception was horrible. My understanding is that this user interface change cost Ubuntu its spot as the #1 most popular Linux distribution, where it was replaced by Mint, and now MX Linux.

Why did Canonical choose to replace GNOME in the first place? Probably because the first iPad was released in 2010, and at the time, people couldn’t stop talking about how tablet computers were the future. Canonical wanted to capitalize on the latest trend and make Ubuntu more appealing to tablet users. This necessitated a UI redesign with large buttons, something that looked more like iOS. In the process, they seemingly forgot that at the time, there were no tablets to run Ubuntu on, introduced many new bugs, and quickly alienated their existing user base, overwhelmingly running Ubuntu on laptops and desktops.

As of 2020, Ubuntu is back to running GNOME, and the most innovative feature to have been introduced to tablet computers is a detachable external keyboard, effectively turning said tablets into laptops. I don’t want to sound cynical and overly conservative. I love building new things, and I think that reinventing the wheel can be a valuable learning experience, but it seems obvious to me that sometimes, there’s a lot of value in stability and predictability. Some things should be reinvented, but in other cases, things don’t really need to change. We badly need electric cars and green energy, but maybe we don’t need that user interface redesign.

In software and hardware design, the things that we should be the most wary about breaking, are the interfaces that people rely on. APIs are an obvious area where stability is particularly valuable, and backward compatibility is crucial. Linus Torvalds is known to have vehemently defended a policy that the Linux kernel should never break user space. This policy makes sense, considering that the interface that the kernel exposes to software is one of the most basic and foundational APIs there is. If the kernel routinely breaks programs and libraries, that makes it very difficult to build anything on the platform.

It’s not just APIs though, it’s also programming languages. Many languages add new features all the time, and in the process, break existing software. It’s hard to build something when the ground is constantly shifting. Companies large and small, as well as individual developers, spend a huge amount of effort simply reacting to change and fixing what was broken. This has made me think that, when developing and growing a programming language, you’d probably be doing your existing user base a favor by prioritizing, stability, bug fixes and performance improvements over the constant addition of new features.

I think that what motivates the constant new feature additions we see in JavaScript, Python and Ruby and other languages is not purely a desire to help programmers be more productive, but also a drive to keep up with the Joneses and maintain some competitive edge over other languages. Language designers are worried that new users will flock to whichever language has the newest, trendiest features.

There is probably some truth to the idea that many newcomers will go for the latest features. However, on the flip side, I’ve been wondering if there can’t be a competitive edge in designing a language that is minimalistic, stable and slow to evolve by design. My personal preference is for languages that avoid hidden, complex, automagic behavior. I also think that there is value in choosing a syntax and semantics that uses broadly understood primitives. After all, the main value of a language is in being understood.

Maybe Planets are Overrated?

Torus_Cutaway_WEB

If everything goes according to plan, 2020 should see the US finally regain the ability to launch humans into space, thanks to the Boeing Starliner and the SpaceX Crew Dragon capsule. That’s exciting, but what’s even more exciting is that, thanks in part to NASA’s decision to fund private space ventures, we’re witnessing the beginning of a new space race with some ambitious goals: Elon Musk has announced plans to use SpaceX to begin colonizing Mars within the coming decade.

You have plenty of reasons to be sceptical of Elon Musk’s ability to start colonizing Mars within 10 years, but I think that competition to be the first to land humans on a new planet could inspire a new generation of scientists, engineers and dreamers to a degree that no other technology has done in the past several decades. I know that the new space race, and TV shows like The Expanse, already have me thinking about the next step, and the technological feasibility of humans colonizing planets outside of our solar system.

There are some bad news in this area. The closest star system, Alpha Centauri, is 4.37 light years away from Earth. That means it would take you over 40 years to reach this place if you could travel at an amazingly fast 10% of the speed of light, and it looks like it’s probably not going to be possible to travel faster than light in this universe (sorry). Alpha Centauri has three stars, making it factually awesome, but only one confirmed planet, which is unlikely to be habitable due to proximity to one of the stars and stellar winds blowing away any atmosphere.

Thankfully, there are other nearby star systems besides Alpha Centauri, but they’re farther away. We might need 50, 60 or 80 years to reach them. Because the journey will take so long, with current technology, we would need to build massive starships, on which we’re able to grow food, recycle water and other waste, provide entertainment for a large crew, as well as raise children. The minimum number of people needed to maintain sufficient genetic diversity for a space colony is somewhere between 80 and 160. However, if you want to avoid psychological distress, minimize risks due to accidental deaths or murderous psychotic episodes, and bring many specialized experts, you may want to send at least a few thousand people along. Since you also need to bring propellant, food, water and equipment, we could be talking about a spaceship the size of a city or small town.

In terms of equipment, if your hope, once you get to another star system is to land everyone on a foreign planet, plant a flag and setup a little base in which you will grow food, you will likely need to bring thousands of tons equipment. That will make your interstellar spaceship even bigger and heavier. Landing on a planet can require a lot of heavy equipment (heat shields, propellant, engines, space suits), and it’s also very dangerous. How do you feel about riding a space capsule that’s been in storage for 80 years through an unbreathable alien atmosphere at 28,000 kilometers per hour on rocky alien terrain? There are worse news still, which is that if anything goes wrong on the surface, your capsule doesn’t have the propellant or ability to take off again, because weight had to be minimized.

I’m sure that plenty of space nerds and technophiles will make the argument that maybe in 300 years we’ll have much more advanced technology than we do now, and some of these problems will be alleviated. That’s possible, but these problems can’t be completely eliminated. What I want to suggest is something simple: wanting to colonize alien planets upon arriving to a new solar system might be a nearsighted idea. You might be thinking you would want to do that just because you’re just used to living on planet Earth, and you’re lacking the perspective of someone who’s used to living in space.

If you imagine that a group of 3000 people traveled from Earth to an alien solar system for 50 or 80 years aboard a large spaceship, and children were born on that spaceship during the journey there, then maybe you can also imagine that these people are actually pretty used to living in space. What if that spaceship had artificial spin-gravity created using centrifugal force? What if it had indoor greenhouses with fields, trees, flowers, gardens and animals? What if was its own little city with houses, movie theatres, bars, workshops, bumper cars, dance floors, romantic spots, waterfalls and zero-gravity gyms? What if there were musicians, dancers and all kinds of artists living there? Maybe it could be an ok place to live. Maybe, when you got to an alien star system, you wouldn’t really want to risk your life riding a minimalistic space capsule to a cold rocky plane so you can go live in a space-tent and farm space-potatoes.

I think that if we can develop the technology to sustain humans in space for 50+ years, we would also be capable of actually living in space without needing to land anywhere. Our own solar system, past Mars, has an asteroid belt, as well as very many moons. Landing on asteroids and taking off afterwards takes much less energy than landing on an Earth-sized planet, because asteroids have much weaker gravity and no atmosphere. Most asteroids are space-rocks, but some of them are rich in metals, silica and even water ice. The composition of asteroids can be evaluated from far away using fancy technology we already have such as radars and lasers. We’re already be capable of building probes and sending them to the asteroid belt to catalogue and tag asteroids.

Interestingly, it could also be possible to land a ship on an asteroid, attach engines to the asteroid, and turn said asteroid into a spaceship or space station. Once on the asteroid, you can begin drilling to build tunnels and homes inside. This concept has been explored in the science fiction novels and TV series The Expanse, in which a human people called the Belters are native to the asteroid belt.

Once you’re living in space, some things also become a lot easier to do than they are on Earth. Think about manufacturing for example. In space, with zero or very low gravity, you don’t need massive cranes to lift concrete or metal beams. You don’t necessarily need energy-hungry vehicles to carry people either: in zero gravity, you could conceivably fly inside a large space station by holding onto a USB fan plugged into your smartphone (or you be less lazy and use some kind of fan-bike). It’s possible to create artificial spin-gravity by rotating a large ship or space station fast enough to push people to the edges (think merry go round, minus the head injuries). However, in a few centuries, we might not care about recreating gravity anymore. It’s conceivable that humans could be genetically modified to live in zero gravity without health risks (explored in the Hyperion series of novels).

Maybe, just maybe, we could save a lot of weight, save energy energy and save lives by going to other solar systems without bringing terraforming equipment and landing gear. We could instead, once we’re there, build bigger, prettier, cozier space stations instead. That doesn’t mean we wouldn’t eventually decide to colonize the local planets, but I think there’s a case to be made that it could make the journey easier, safer and more comfortable for everyone involved to embrace living in space instead of making planetary colonization the priority.

You might be tempted to tell me that space radiation is dangerous, and so is mining asteroids, but I’m going to respond that you might not be really thinking this through. Space radiation has to be addressed for any kind of planetary colonization, even if you’re only going to Mars, since Mars has a very thin atmosphere which won’t protect you. Space mining could be done using a variety of relatively safe techniques. You could park your space station 500 kilometers away from the nearest asteroid, and have robotic probes fish asteroids back by securing them with giant nets and slowly reeling them in, without any humans needing to leave the space station and without needing to accelerate the asteroids to dangerous velocities. I’m going to argue that landing humans on an alien planet and surviving there with minimal equipment and no backup is much more dangerous than having a well-equipped, trained crew mine asteroids using robots.

In the near term, I believe there’s a legitimate argument to be made that instead of thinking about colonizing mars, it could make more sense to think about building space stations that are completely self-sufficient and appropriately shielded from radiation. These stations would just as well, if not more effectively than Mars colonization, achieve the purpose of “backing up humanity”, as Elon Musk put it. As an additional benefit, once we are able to build space stations that can fully sustain themselves long term, then we will be much closer to being able to build spaceships that can travel for decades without stopping or being restocked with new supplies, or self-sustaining Mars colonies.

It’s Been Done Before

I’m someone who comes up with a lot of ideas. When I was a teenager, I used to constantly get excited about new projects, and I found myself often getting sidetracked, ditching existing projects before they were finished so I could start something else. It took me years to learn the discipline to choose and stick with a limited number of projects. They say that ideas are a dime a dozen, but I would say that some ideas are definitely worth much more than others. Your strongest asset, as a creative person, is to develop the ability to recognize which of your ideas have real potential, and are truly worth spending your time on.

Nowadays, when I have an idea, I often write it down and set it asides. If it’s a really interesting idea, I’ll come back to it later, and maybe flesh it out a bit. I think it’s important to figure out the details, but also to criticize your own ideas a bit, by thinking of them in adversarial terms (how could this fail?). This is a gradual, iterative process. The more fleshed out an idea, the more layers of adversarial testing it passes, the more it becomes worth spending time on. Ultimately, before you invest any real effort in a new idea, it’s also worth thinking about whether you have time to do so, and how this would affect the other projects you’re working on, and the people you’re working with.

Once I’ve sufficiently fleshed out and tested an idea in my head, if I’m still excited about it, I’ll want to discuss it with other people. That will help me get useful advice, outside perspectives on how to improve the idea, and maybe even recruit some help. At this point though, the same thing always happens, I’m inevitably going run into one or more people who give me a variant of “it’s been done before”. These people will point to some existing project that they believe is similar to what I’ve just described. Sometimes they mean well, and are just trying to help me differentiate my project or help me avoid spending effort on what would be a dead end. Sometimes it seems like they are cynics who can’t stand to see that I’m excited about something. I try to avoid working with the latter kind of person.

The most cynical among us would tell you that in movies, literature, and music, there are no more new ideas. It’s all been done before, “what’s old is new again”, all possible thoughts have already been conceived, and we’re doomed to forever rehash the same old ideas over and over again. There’s some truth to it: how many songs and movies are about boy meets girl, or the feelings that follow a bad breakup? The more songs and movies are written, the more various concepts and ideas have been explored, and the harder it becomes to come up with something truly groundbreaking and innovative. There is one caveat to this, however, which is that the world is changing constantly. What will love be like in the year 2073? It might not be quite the same as in 1982.

Your idea isn’t novel. Any software-related idea that you’ve had, someone implemented it on a Lisp Machine at MIT back back in 1977. Unfortunately, the backup tapes have been lost in a fire and there’s no evidence left, I have no material proof, so you’ll just have to take my word for it, someone did beat you to the punch.

It’s happened many times that someone told me that “it’s been done before”, without being able to actually provide any reference to a similar idea. It’s happened that, after I did some digging, I found that whatever idea the person cited was only superficially similar to what I had suggested if you squinted really, really hard. There’s also been times where someone pointed me to an existing project that was a very poor execution of my idea and basically told me that because this project had failed to take off, the idea would obviously not work.

Before you embark on a project and really invest yourself in a new idea, you should do some research and look at what’s already out there. It’s quite possible that you’ll find that your idea is not as novel as you thought it was. Still, I think that in the world of software, the worldwide context is always changing. It’s quite possible that as you start doing some research, you’ll find that others have tried to do something similar to what you want, but they didn’t execute well, or they simply had the right idea at the wrong time. Just think about electric cars. There have been many failed attempts (dating as far back as the 1890s) before there were successful commercial products. Finding such failures will provide you with an opportunity to learn from the mistakes of others.

Ultimately, having a truly novel idea might not even matter. If you have an idea for some kind of accounting software, and you find that your would-be competitors are raking big profits selling something completely broken, you might be able to eat their lunch just by executing reasonably well. It can also be a fun learning experience to recreate an existing system without necessarily looking to innovate on its design. If you have an idea that really has you excited, go for it. It’s important to have realistic expectations: you may not succeed, but you will definitely learn something along the way. One thing is for sure, which is that you’ll never succeed if you don’t even try. What’s the point of living if you’re not having any fun? Explore.

They Might Never Tell You It’s Broken

This blog post is a public service announcement (or maybe a reminder) for anyone working on a programming project that they already have, or intend to release to the public, be it as something open source, a pet project, or a startup.

I’ve worked on a few successful open source projects over the last 10 years. I would consider these projects successful in that they got hundreds of stars on GitHub and each attracted multiple open source contributors. I actually shut down one of these project because reviewing pull requests alone was becoming a second unpaid job on top of my regular job, taking multiple hours out of my evenings after work, which became exhausting, but that’s a story for another post. What I want to tell you about today is something important, that I believe any developer should know, but I personally didn’t understand until I had been working on open source projects for a few years.

As part of my PhD, I developed Higgs, an experimental JIT compiler for JavaScript written using the D programming language. I developed it on GitHub, completely in the open, and wrote about my progress on this blog. Pretty soon, the project had 300 stars on GitHub, a handful of open source contributors, and I was receiving some nice feedback. It made me happy to have so many people taking notice of my research work. As part of Higgs, I had written my own x86 machine code generator, which enabled it to do machine code pirouettes LLVM couldn’t. I did all my development on Linux, but had done my best to keep the code as portable as possible, and so, that code would work fine on MacOS as well, I had assumed. Unfortunately, I was wrong.

About a year into its development, Higgs had enough of a small community that it made sense to have create a chat room to exchange with other contributors and users. About a dozen people joined over the next two months. One day, someone I had been exchanging with on the chat room for two weeks reached out to me to signal a strange bug. They couldn’t get the tests to pass and were getting a segmentation fault. I was puzzled. They asked me if Higgs had MacOS support. I explained that I’d never tested it on MacOS myself, but I couldn’t see any reason why it wouldn’t work. I told this person that the problem was surely on their end. Higgs had been open source for over a year. It was a pretty niche project, but I knew for a fact that at least 40-60 people must have tried it, and at least 50% of these people must have been running MacOS. I assumed that surely, if Higgs didn’t run on MacOS at all, someone would have opened a GitHub issue by now. Again, I was wrong.

The problem, it turned out, was that MacOS had more strict requirements for keeping the stack pointer aligned. This wasn’t difficult to fix. The more important lesson, that I didn’t understand until that point, is that you can’t count on the people trying your project to quickly and reliably signal bugs to you. Most of the time, if it doesn’t work, they won’t report the problem. There are a few reasons why this might be:

  • They assume that someone else has already reported the problem, and there would be no point in saying anything. The bigger your project, the more likely people are to assume that someone else has already reported the issue.
  • They think the fault might be on their end, they may be confused and feel too embarrassed to reach out for help. Nobody wants to look stupid or get told to RTFM, and so, they choose silence.
  • They are just trying your project out of curiosity, and are in no way invested. They will find an alternative to your project, or go do something else.

It’s a horrifying thought, but it could be that for every one person who opens an issue on GitHub, 100 or more people have already tried your project, run into that same bug, and simply moved on. So, what can you do? You can encourage people to report bugs. I visibly write in my GitHub README that reporting bugs is encouraged and welcome: “Please tell me if something is wrong, you’re helping me make this project better.” Another obvious thing that you can do is to have robust automated testing. Some continuous integration services can automatically test on both Linux and Mac.

More broadly, if you want your project to be successful, I think it’s important to try and put yourself in the user’s shoes. Every once in a while, try installing your software from scratch, along with all the dependencies. Ideally, you want your installation process to be as simple and frictionless as possible. If your software requires the user to perform 20 steps to get it running, you’ll be losing potential users even before they have a chance to figure out if it works on their system or not. In general, I find that writing software with a minimalist design philosophy, minimizing external dependencies as much as is reasonable to do so, will help you avoid bugs, and streamline your installation process.

Balancing Fun, Stress and Profit

A little over a week ago I launched Zupiter, a browser-based music app I created over the last 8 months or so. It’s a minimalistic modular synthesizer that runs in a web browser. It’s pretty basic, and it will never replace something like Ableton Live, but the appeal is that anyone with Chrome or Firefox can make music instantly, for free, without having to download or install any software, and then share what they’ve created with friends online.

For fun, I did the launch in two parts, online and in the real world. I started by writing a post on this blog, which someone shared on Hacker News, where it remained on the front page for about 12 hours. Zupiter was later featured on Hackaday. A few days later, in the real world, with help from multiple friends, I organized a fun little launch party, featuring a live demo and performance in conjunction with Montreal-based musician Feren Isles. Since then, the app has gained a little bit of traction. The app has been visited over 29,000 times, over 260 people have created accounts, and together these people shared more than 500 projects created using Zupiter.

 

The app got a little bit of traction, and then I couldn’t help but ask myself “what’s next?”.  I have to admit, I’ve dreamed about this turning into a side-business, a startup, maybe an SaaS that can bring income. Who knows, maybe enough income that I can be my own boss one day. The only problem is, I don’t think I’m anywhere close to that. In order to get there, the app needs many improvements. It also needs a massive amount of promotion. Furthermore, I started to realize something that should have been obvious from the start.

I read an article a few days ago where Takuya Matsuyama, creator of the Inkdrop app, casually mentioned having made over $9K in sales after making the HN front page. I made the HN front page with my app too, and two people donated a total of $20 via PayPal. I’m thankful for those two donations, and I promise to the donors that I will use this money wisely. However, this article made me realize that when it comes to turning in a profit, I’ve been doing it wrong. One important detail struck me, which should have been obvious from the start: browser-based apps are most probably not where the money is.

Inkdrop sells monthly subscriptions through the Android and Apple app stores. If I want to make money with music software, I should probably be making mobile apps, because there is infrastructure set up for people to buy mobile apps, and a culture of people doing so, but that same infrastructure and culture doesn’t really exist for browser-based apps. The truth is, if I want to be making money, there’s a lot of things I should be optimizing for, which I totally haven’t been. Thinking of all those things I maybe could, or should, or would have to do got me feeling somewhat anxious, stressed, and then sad.

There’s a reason why I designed Zupiter as a browser-based app. I did it because I felt there was a niche to be filled. There are a lot of music apps for mobile, but what’s available in terms of browser-based music software is still fairly limited. I created Zupiter because it’s a tool that I myself want to use for sound design, and I wanted to use that tool on a 32″ widescreen display, with a MIDI controller, not so much on a phone or tablet. Beside that, I created Zupiter because I wanted to have fun.

There’s been other discussions on Hacker News, relating to Takuya’s article, and many of the commenters pointed out that there’s often a difference between a side-project and a business. A side-project is something you do for fun in your free time. Running a business, however, requires doing a ton of extra work that isn’t development, and making a lot of tiny decisions at every step of the way that result in optimizing for growth, and ultimately, for profit.

To me, that seems stressful. I already have a full-time job. It’s a fun, creative and interesting job. It’s also demanding enough that I don’t want to come home from work and start to stress about optimizing my side-project for profit and worry about missed opportunities. I don’t think I have the bandwidth for a second job on top of my job. The amount of work required to get to a stage where I could support myself from this source of revenue would likely push me into a burnout. At this stage, I’d rather optimize for fun than for profit. I want to manage my side-projects in a way that I try to keep it fun and avoid having it become an extra source of stress.

At this time, I don’t think I can bootstrap a side-business all on my own, it seems like an unrealistic goal for me to pursue, but that doesn’t mean it’s impossible for Zupiter and future music apps I create to bring in revenue. One of the people who showed up at my launch party was Devine, co-creator of Orca, a nifty programming language for livecoding musical patterns. I was amazed to learn that he lives with his partner on a sailboat in Japan, and makes a living creating (very cool) content and crowdfunding through Patreon.

Devine’s story got me thinking that maybe I can do something like this too. I don’t really want to develop for mobile and optimize for profit right now. I also don’t really want to quit my job and live on a sailboat, but I do want to keep creating useful software and content and share it with the world, and it would be cool if there was a way that I could save up enough to take a few months off to work on my side-projects full time someday. I went ahead and created my own Patreon page so I can get the ball rolling. In the meantime, I don’t want to focus on optimizing my side-projects for profit and growth, because I want to make sure that working on these remains fun.

The realization that Zupiter may never turn into a profitable side-business has been a bit discouraging for me, but I think I’m being honest in saying that building Zupiter has been fun and rewarding so far. I’ve accomplished an important personal goal with this project: I built my dream music making tool. Others are using this tool and finding it useful. They’ve created awesome and beautiful things with it, things I wouldn’t have built myself. Every day during the last week, I listened to the projects people shared, and found myself surprised, impressed and even a little tearful at times.

 

Zupiter: a Web-Based Modular Synthesizer

When I was a kid, I thought I didn’t like music, other people really enjoyed it, but I just didn’t get it. This all changed when I was 12, and I first saw the movie “Hackers”. You can think whatever you want of that movie, whether you think it’s a classic or everything that’s wrong with Hollywood, it had a mind-blowing soundtrack featuring several pioneering electronic music artists such as The Prodigy, Orbital and Underworld. Ever since I was exposed to this, I’ve been in love with electronic music.

In my mid-twenties, after I’d learned how to program, I started to wonder if there was a way that I could combine my passion for programming with my love of electronic music. I started reading books about sound synthesis, composition, etc. I wrote a web-based music app, MusicToy, back in 2012. This app originally used the Mozilla Audio Data API (this was before the Web Audio API was made available). The app is super simple, but that was the point, I wanted to create something that was beginner-friendly, and could allow anyone to create a fun pattern, without having any knowledge of music theory.

Today, I’d like to present to you Zupiter, a browser-based web app I’ve working on in my spare time for the past 8 months. It’s a modular synthesizer that runs in a web browser. You can use it to build a custom synthesizer using a visual programming language inspired by Pure Data and Max/MSP.

The app is written entirely in JavaScript and makes use of both the web audio and web MIDI APIs. You can play notes using your computer keyboard (A to L keys), using a built in sequencer node, or you can connect an external MIDI keyboard or sequencer to your computer and use that to play a synthesizer you created in Zupiter. The app also makes it possible to map physical knobs on an external MIDI controller to virtual knobs in the app, just by double-clicking on a virtual knob and then wiggling the knob you want to map on your device.

I created the app because I wanted to have a powerful tool that would allow me to experiment and understand exactly how specific sounds are made. I also created it because, to my knowledge, there is nothing else quite like it. Yes, there are already other browser-based music apps, but to my knowledge, at this time, no other browser-based music app offers this degree of flexibility and power.

Using Zupiter, you can build your own synth from your browser, without spending any money or installing any software. You can then share what you just created with friends instantly, by going to the Share tab. Your friends can then hear what you just made, modify it, and share a new version of it, also without installing any software on their machine. My hope is that Zupiter will lower the bar to entry, and get more people excited about making music.

If you’re curious about trying Zupiter, but a little confused about how it works, here are some examples to get you started:

Zupiter isn’t perfect, it’s only been tested in Chrome and Firefox, and it’s very possible you may encounter some bugs, but I’m really excited and curious to see what you can make with it, and I encourage you to share what you create. If you’re confused as to how it works, there is a Help tab in the app with some basic examples and instructions, and I’ve created a subreddit where you can ask any questions. Your feedback is more than welcome!