en en en pt es en en en en cv en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en de en en en en en en en en en en en en en en en en en en en en en en en en en en en en fr fr zh nl en en en en en en en en en en en en en en it en en en en en en en en en pt en en en en en en en en en en en en en en
Before I went to see Blade Runner 2049, I sat down with a friend to re-watch the original Blade Runner from 1982. At the beginning of the movie, there is a grim portrayal of the future. A title screen reads “Los Angeles: November 2019”. We are then shown a dark city obscured by smog, with tall buildings and even taller chimneys that have columns of oil fire and smoke projecting upwards.
It’s 2018, and there are a lot of things to be upset and worried about. The sum of all human knowledge has never been greater than it is now, but unfortunately, our world seems to be ruled by plutocrats, and divided by identity politics. The stock market is negative for the year, and the sky might be just about to fall, or so the news media would have you believe. Thankfully, the world is not yet as grim as what Blade Runner projected, and with any luck, it probably won’t be so grim in November 2019 either.
I’m very optimistic about green energy. I have been a Tesla shareholder since 2016, and it has been amazing to watch that company’s progress. Despite all the negative press, they have produced and sold over 200,000 electric cars in 2018, and produced a profit that beat estimates in the last quarter. The nay sayers will tell you that Tesla produces luxury cars which are out of reach of the masses. That’s currently still true, but Tesla has been sticking to its plan, which is to produce cheaper and cheaper cars as they perfect the technology and achieve economy of scale. Their cheapest car, the mid-range Model 3, is currently priced for $45,000 USD, which is a lot cheaper than the first car they ever sold, the Roadster, which sold for $122,000 USD (adjusted for inflation).
In my opinion, Tesla is succeeding in its stated mission: “to accelerate the world’s transition to sustainable energy”. China and Europe are ahead of the curve in electric vehicle production and adoption, but Tesla, GM and Nissan are already selling electric cars in the US, and almost all major automakers have announced plans to begin producing them as well: even Ford has announced a Mustang EV. Tesla is forcing every automaker to see the obvious: if you can make them cheap and give them enough range, there is massive pent up demand for electric cars. The electric car revolution is happening, for real.
The common argument against electric cars is that the electricity they use is often produced from non-renewable sources, negating their environmental benefit. I’ll begin by stating that this isn’t true everywhere. Quebec, the Canadian province where I’m from, produced 95.2% of its power from hydro, and 3.6% from wind in 2016. However, even if all the power in the world was generated by burning coal, the fact is that industrial power plants are much more efficient at converging fossil fuels into energy than car engines. They can be made more efficient because they don’t have the same size and weight constraints as car engines do.
Many will argue that solar power and wind can’t possibly replace fossil fuels because the sun doesn’t always shine and the wind doesn’t always blow. This problem is being addressed as well. Tesla are building large batteries that can be installed in your home or at large power plants. Multiple startups are also working on utility-scale energy storage solutions. The cost of renewable energy technologies is still a little steep, but solar panels, windmills and lithium-ion batteries have been steadily becoming more affordable every year.
Currently, it’s possible to buy and install a 5KW solar setup that includes a home battery for about $15,000 USD. This is enough for one person to live completely off the grid. That price may seem high, but if you amortize it over a 20 year mortgage, and you factor in energy savings, you realize that it’s already within reach of many people. Assuming that the cost of solar cells and batteries keeps falling, we will soon reach a point where renewable energy is available 24 hours a day, and cheaper than fossil fuels. When this happens, it will be economically unjustifiable to use fossil fuels for energy, and the transition will not only be quick, but also inevitable.
Global warming is still a problem, particularly if you take into account the runaway greenhouse effect. However, the transition to renewables could happen faster than you think. It’s not unrealistic to think that in less than 5 years, electric cars will be about as cheap as gasoline cars, and in less than a decade, we may see some oil and gas corporations going bankrupt. It’s also very possible that the cost of solar cells and energy storage will keep going down even after they become price-competitive with non-renewable energy technologies. Within this century, we may enter an era where energy is cheap and plentiful.
That’s great, but what about all the other problems in the world? If you look beyond the negative headlines, there are many reasons to remain optimistic. According to multiple sources, the number of people living in conditions of extreme poverty is hitting an all time low. It’s also likely that cheaper and cleaner energy will help us not just with clean air, but also alleviate issues of scarcity in many parts of the world. Solar panels and batteries can produce energy anywhere in the world, and it so happens that many of the poorest countries get plenty of sunlight.
Building a Simple Self-Driving Car Simulator
The course has, so far, been focused on traditional robotics methods using computer vision and PID controllers to drive the robots. However, students and professors are becoming increasingly interested in using deep learning (and reinforcement learning in particular). Since reinforcement learning needs a lot of data, it’s much more practical to do it in simulation than with physical robots. This has been one of the main motivations for building a simulator.
The simulator I’m building works as an OpenAI Gym environment, which makes it easy to use for reinforcement learning. It’s written in pure Python and uses OpenGL (pyglet) to produce graphics. I chose Python because this is the language most used by the deep learning community, and I wanted for students to be able to modify the simulator easily. The simulator performs many forms of domain randomization: it randomly varies colors, the camera angle and field of view, etc. This feature is meant to help neural networks learn to deal with variability, so that trained networks will hopefully work not just in simulation, but also in the real world as well.
Because Duckietown is a toy universe that is essentially two-dimensional, I’ve designed a YAML map format which can be easily hand-edited to create custom new environments. It essentially describes a set of tiles, and where to place 3D models relative to those tiles. I’ve also made some simplifying assumptions with regard to physics (the agent essentially moves along a 2D plane).
While working on this simulator, I’m also experimenting with sim-to-real transfer, that is, getting policies trained in simulation to work with a real robot. This is a work in progress, but we are close to having this working reliably. The video below shows some promising results:
If you’re interested in playing with this, the source code is available on GitHub. Feedback and contributions are welcome. If you run into any issues, please report them, as I’d like to make the simulator as easy to use as possible.
(Spread)sheet Music: Making a Simple Music Sequencer using CSV Spreadsheets
On Friday night, I put together a little hack that I found quite amusing. It’s a music sequencer that uses CSV spreadsheets to loop and sequence beats. It has the useful feature that you can save the spreadsheet, and it will periodically reload it, so that you can edit and jam with your sequences live. Best of all, it’s around 100 lines of Python code, comments and all. I posted a video I recorded on twitter, and the reception was very positive, so I thought I would provide a short writeup, and make the source code available as a gist for anyone interested.
You might wonder why I wrote this program, besides the humorous and attention-grabbing aspects. Clearly, there are already a variety of sophisticated programs (DAWs, Digital Audio Workstations) such as Ableton Live out there which can do much more complex things. Part of the motivation is that I like to play with music programming, and by writing my own code to sequence music, I can write a program that will have exactly the workflow and features that I want.
One of the things that I wanted to play with, here, was the ability to create melodies using only the notes in a given scale. Ableton Live Lite, or at least the version I have here, for all its powerful features, doesn’t have a mode that will highlight a given scale (at least not without plug-ins). I think there is a lot of value in being able to write software with an interface that is fully customized for the things you want to play with, and in this case, writing a music sequencer is trivially easy, so why not?
The spreadsheet sequencer uses the mido package to send MIDI output to hardware synthesizers that I have at home, namely a Novation Bass Station II and an Arturia Drumbrute. These are directly connected to my Linux PC using USB. Note that you do not need to own hardware instruments to play with Python and MIDI. I play with hardware synths because I enjoy having physical knobs I can turn, but there are many free software programs that will connect via the MIDI protocol, both synthesizers and samplers.
It’s also possible to use MIDI for input. There are devices called MIDI controllers which can connect to your computer via USB. These can be keyboard, or boards with physical knobs you can turn to adjust parameters as you jam live. You can try searching for MIDI controller on eBay if that’s something that interests you. There are some used ones you can get for very cheap.
To conclude, I will note that although I came up with the idea on my own, I wasn’t the first to think of using a spreadsheet program to sequence music. I hope that this post has encouraged you to explore your musical creativity, or just to program something fun :)
I’m 32, and I’ve been programming actively for over 16 years at this point. I don’t have a lifetime of experience doing this, but over the years, I’ve come to develop a certain style, a kind of philosophy or methodology that I try to apply in everything I do. Crucially, I would say that I’m a minimalist. I like to build things that are only as complex as they need to be to accomplish their purpose. I like to distill ideas to their simplest form.
Much of what I will discuss in this post may seem like common sense to many of you. I’m probably not the first one to tell you about the principles of KISS and YAGNI. Unfortunately, I think that the art of building simple, robust engineering is something that is rarely taught in universities, poorly understood, and often disregarded. We live in a world full of bug-ridden, poorly written software, with a thousand useless bells an whistles. I don’t believe it has to be this way. In my view, much of the bugs we encounter could be avoided if more programmers followed some basic principles to minimize complexity.
Back when I was a teenager, back in the early 2000s, one of the first programming projects I embarked on was some ambitious 3D game. I recruited several people to work on this project with me. We produced a lot of art, and we did implement a game engine and even a map editor. We had some nice screenshots to show. Unfortunately, no game ever came out of it. One of the main issues is that there was a lack of focus on my part. I wanted to build something more awesome than Unreal, Quake 3 and Half-Life, and I thought I needed killer tech to do this, but I didn’t really have a specific game in mind. I had no specific goal, and so no concrete plan. I would guide the project in whatever direction seemed most interesting at the moment. Every two weeks, I’d start working on some new feature for the game engine, but never quite finish it. We most likely could have built a game, if I’d been willing to aim at a simpler, more realistic objective.
These days, before I even start on a new project, I try to spend some time doing some research to convince myself that this project is worth doing, that I have the time to do it, and that I can set realistic goals. I try to start small. I ask myself what is the smallest, simplest version of my idea that I could implement, with the least amount of features, and I try to plan out the steps I will need to complete to get to that. Simply put, the first step, in my view, is to clearly outline what the Minimum Viable Product (MVP) is going to be. Defining an MVP helps me stay focused, and it also ensures that I have a goal simple enough that I can be sure I’ll stay motivated long enough to get there.
Many people make the mistake of thinking that if they don’t immediately account for all the features they could possibly want to add to a project from the beginning, they might paint themselves into a corner, unable to refactor the code, unable to bring the project where they ultimately want it to be. My counter-argument would be that refactorings are inevitable. You will make design choices that turn out to be wrong. You will need to change your code. You simply can’t account for every possibility and every single interaction from the beginning, because there are too many unknowns. If you start with an MVP, you will gain a lot of insight in the process. You will also have a working product that is very simple, and so very easy to refactor.
Trying to build simple products will help you keep people motivated, gain insights, and ultimately reach your goals. It might also help you avoid bugs. Less code means less corner cases, less things to test, less that can break, and less to debug. This is something that good engineers understand very well. When you minimize the number of moving parts, when you minimize complexity, you minimize the chances that your product, and your project, will fail.
I think most of what I’ve said so far is commonly accepted wisdom among seasoned programmers. What I’d like to bring up next is that minimizing the complexity of your software, eliminating possible points of failure, is not just about simplifying the code you write. In my opinion, it also applies to the things your software stands on. The software you build necessarily makes a number of assumptions, and has external dependencies. Most programmers, it seems to me, follow the “don’t reinvent the wheel” philosophy. If something has already been implemented, you should just use it, never implement your own. This is seen as a way to minimize the complexity of your software. The problem is that not all external dependencies are created equal.
Every library that you import is a piece of software you don’t have control over. It’s something that needs to be built and installed in order for your software to run. It’s a black box with its own many dependencies and possible points of failure. How often have you tried to install a library or piece of software and found that it was broken out of the box? If your software has 15 external dependencies, then quite possibly, over the next year, one of these will break, and your software will be broken along with it. If you’re programming in Python, chances are that your software will break several times over the next few months, as packages are being changed and broken under your feet.
When I write software, I try to minimize the number of dependencies I rely on. I do this both to minimize possible points of failure, and to make sure that people installing my software won’t have a terrible time getting it to work. When I have to rely on external dependencies, I try to pick the ones that are more established and well-maintained rather than obscure ones. Sometimes, I will “reinvent the wheel”, when I judge that the effort required is small enough. Obviously, this doesn’t always make sense. If you roll your own crypto and you’re not a crypto researcher, you deserve to be slapped upside the head. However, if you need to load textures in your indie game, you very well could implement a parser for 24-bit TGA images instead of relying on some library which itself has 50 external dependencies. This can be done in less than 100 lines of code.
There are other ways in which you can minimize points of failure and make your software more reliable. You can prefer simple file formats, prefer open standards, and avoid proprietary solutions. Ultimately, the best way to keep things simple, however, is to simply have less features. I’m a minimalist. I prefer to build software that does one thing and does it well. Ultimately, you’ll never make everyone happy, you’ll never satisfy every use case, not without contorting your design into something unmaintainable and fragile.
My new Job in RL & Robotics Research
After I completed my PhD in early 2016, I took a job with the GPU compiler team at Apple and moved from Canada to the United States. I wasn’t sure if Silicon Valley was for me, but I figured that if I was going to try living in another country, it was best to make that kind of move when I was young, without property, children or a life partner.
My job at Apple was in many ways a dream job. It was sunny almost everyday, I worked on a small team of highly qualified friendly engineers, had an awesome boss, ate lots of insanely great organic food, and spent my work days sitting in a comfy Aeron chair. Unfortunately, I wasn’t quite happy there. For one thing, I didn’t quite mesh with Apple’s secretive culture. I didn’t love the culture of Silicon Valley that much either, but the biggest problem was that the isolation got to me. Living in an American suburb far from everything I knew, and dealing with illness in the family back home, I ended up having to take antidepressants for the first time in my life. I decided to move back to Montreal, the city I love, in the hope of living a healthier and happier life.
It’s been nine months since I started my new job as a staff member slash research assistant at the Montreal Institute for Learning Algorithms (MILA). It’s one of the biggest (if not the biggest) university research labs focused on artificial intelligence, headed by Professor Yoshua Bengio. This job doesn’t come with a Silicon Valley salary, but in my view, it’s a good mix of the perks I could get in an industry job, combined with the freedom that comes with academic research. The schedule is very flexible, the work is highly experimental, and best of all, as a research assistant, I have the opportunity to publish, but not the obligation.
You might be surprised at the current shift in career plans. I did my PhD in compiler design, so why am I working in a deep learning lab? Obviously, there’s a lot of excitement surrounding machine learning and AI right now. I, like many others, believe that this technology will transform the world in a million ways, most of which we haven’t even begun to imagine. That’s one reason why I’m here: I’ve shared that excitement for a long time. However, that’s not the only reason. Fundamentally, I like research. This is a very active area of research. Compilers, as cool as they are, are not a very active research topic anymore. Most industry compiler jobs revolve around maintenance, and implementation of tried-and-tested ideas. Most academic compiler research is focused on incrementalism. There unfortunately isn’t that much pioneering.
I feel very fortunate that my new job has allowed me to pick which projects I would get involved in. I’ve chosen to focus on projects in the areas of reinforcement learning and robotics. Reinforcement learning holds a lot of promise as a technique for teaching algorithms new tricks. Robotics has fascinated me since I was a child, and offers me the opportunity to tinker with electronics and more concrete projects. Another great perk of this new job of mine, is that being an academic lab, they fully embrace the open sharing of ideas and information. I will be allowed to blog and discuss in detail the projects that I am working on. Stay tuned!
We All Live in a Bubble
Almost exactly two years ago, Star Wars: The Force Awakens came out in theaters. Hundreds of millions of people (including several of my own friends) were eagerly awaiting this release. I, on the other hand, was completely oblivious. I only found out about the existence of this movie about a week after its release, when I overheard spoken conversations during the holidays. I was surprised and disappointed at my own ignorance. Clearly, I’d been living under a rock.
I am still, in many ways, living under a rock, in my own bubble. I know quite a few things about compilers, machine learning, and the soap opera that is American politics, but I’m largely unaware of what goes on in municipal and local politics, for instance. I also know very little about local (Quebecois) artists and musicians. To tell you the truth, it’s not that I don’t want to know about these things, it’s that this information never makes its way to me, and I don’t go out of my way to find it.
When I was a child and a teenager, I was in many ways more informed about what might be termed “mainstream” culture. Every night, me and my mom watched the evening news and various talk shows. Much of the information we got about our local culture was delivered to us in this form. Today, it seems we celebrate the death of television, the cutting of the cord that came with the arrival of the information age. This is the end of this dominant thread of culture that was imposed upon us, in favor of access to a seemingly unlimited amount of information.
We have the freedom to choose what we’re exposed to. The information doesn’t come packaged and predigested in evening news bulletins ready for mass consumption. The downside of this, however, is that to some extent, we’re all living in our own bubble. There is no longer a common thread of culture that I share with everyone I know. We each can pick and choose what interests us, and ignore all the rest. The thing is, to some extent, we don’t even make that choice.
Facebook, Google, twitter and reddit run some ranking algorithms which we only see the end result of. If I had some input, I would tell Facebook to please show me more information about local news and politics, because I’d like to stay in the loop. Unfortunately, they never asked for my opinion. They’re not in the business of making sure that I’m a well-rounded individual, they’re in the business of capturing my attention, and selling some share of it to advertisers. The unfortunate truth is that in some ways, the internet isn’t so different from television: which information we get or don’t get to see, is a choice that’s increasingly being made for us.
I think the internet has brought us many wonderful things. We have more access to information than ever before. We also have the ability to reach many more people than we ever could. However, it seems to me that our ability to choose is also contributing to worsening social isolation in the modern world. We’ve been given the freedom to find threads of culture online that cater to our precise tastes.  That can be wonderful and enriching, but there is also a huge downside: it also means that people have the freedom to pick a cultural bubble online that is as comfortable as possible, and never make the effort of stepping out of it. The downside is the confirmation bias.
Some political commenters have said that modern politics are becoming increasingly polarized. More and more, things are being spun as left versus right, liberals against conservatives. There’s a lack of empathy, with each side portraying the other as morally bankrupt and unsalvageable. I think that the internet and the attention economy may be largely to blame for this situation. With the internet, no matter how radical your beliefs are, you can find people and sources online who will tell you exactly what you want to hear: that you were right all along, that those who disagree can only be disturbed individuals, and that you can rest comfortably in your sense of moral superiority.
Google, Facebook, twitter, etc. are not concerned with your personal growth, your edification and rigorous fact-checking. They’re also not concerned with your long-term well-being and whether you have healthy relationships with the people who surround you. They’re happy to spoon-feed you a diet of whatever they think you like and will keep your attention the longest. I would say that it’s up to you, me, and all of us to make the uncomfortable effort of standing up, and stepping outside of our cozy little bubble. However, I’m also quite worried that this simply isn’t going to happen, that most of us are going to remain addicted to the information equivalent of shitty french fries, reconstituted chicken meat and flavored sugar-water.
The AI Risk Isn’t What You Think
Recently, a number of prominent figures, including Elon Musk, have been warning us about the potential dangers that could arise if we can’t keep artificial intelligence under control. The fear surrounding AI dates back a long time. Novels and stories about robot takeovers date back as far as the 1920s, before the advent of computers. A surge of progress in the field of machine learning, and the subsequent investment of hundreds of billions of dollars into AI research by giants such as Google, Amazon, Facebook and Microsoft, has brought this fear back to the forefront. People are waking up to the fact that the age of AI and robots is coming soon, and that self-aware AI could very likely become a reality within their lifetime.
The 2014 book Superintelligence: Paths, Dangers, Strategies by Nick Bolstrom embodies this fear. In his book, Bolstrom details multiple scenarios in which AI could spiral out of control. I believe that the author has achieved his goal: he has successfully scared many researchers into paying attention to the existential threat surrounding AI, to the point where AI safety is now a serious field of research in machine learning. This is a good thing. However, I think that Bolstrom’s book is in many ways alarmist, and detracts from some of the bigger, more immediate threats surrounding AI.
Much of the Doomsday scenarios in the Superintelligence book are centered on the idea that AI entities will be able to rapidly improve themselves, and reach “escape velocity” so to speak. That they will go from human-level intelligence to something much beyond in a ridiculously short amount of time. In many ways, I believe this portrays a poor understanding of the field of machine learning, and the way technology usually progresses. I see at least three factors that make this scenario unlikely:
While the idea of an AI entity rewriting its own machine code may be seductive to sci-fi authors, the way deep neural networks operate now, they would be hard pressed to do such a thing, particularly if they weren’t designed with that purpose in mind.
Currently, machine learning researchers are struggling to put together enough computational power to train neural networks to do relatively simple things. If an AI became self-aware tomorrow, it probably couldn’t double its computational power over night, because doing so would require access to physical computing resources that simply aren’t there.
Sudden explosive progress is not the way any past technology has progressed. As rapidly as computers have evolved, it took decades and decades to get from the ENIAC to the computers we have now. There is no reason to think that AI will be incredibly different. So far, the field of machine learning has seen a fairly gradual increase in the capabilities of the algorithms we have. It took decades to get to where we are now.
Silicon Valley likes to tell us that technological progress goes at an exponential rate, but fails to deliver any real evidence backing this dogmatic belief. In the case of self-aware AI, I think a more likely scenario is that we will be building machines with increasing levels of awareness of the world. We’ll build robots to clean up around our homes, and the first ones will be fairly stupid, limited to a small set of tasks. With never generations, they’ll become capable of doing more and more, and understanding more and more complex instructions. Until, eventually, you’ll be talking to a robot, and it will understand you as well as another human being would.
In my opinion, the advent of self-aware AI will require several more breakthroughs in machine learning. It may also require several generations of hardware that is designed with the sole purpose of accelerating neural networks. The good thing is that if self-aware AI takes a long time to emerge, the first general-purpose AIs will have a fairly limited understanding of the world, and limited computational capabilities. This means those first AIs will simply not be capable of taking over the world. It also means we may have several years to test a number of fail-safe mechanisms between the time where AIs start to have a useful understanding of the world, and the point where they are genuinely dangerous.
I think that, in some ways, the focus on the existential threat surrounding AI detracts us from a bigger, more immediate danger. AI is an immensely powerful tool. In the hands of giant corporations like Google and Facebook, it can be used to sift through every text message and every picture you post online. It can be used to analyze your behavior, control the information you see. The biggest risk posed by AI, in my opinion, is that it’s a tool that can be used to manipulate your life in ways that are useful to those who control the AI. It’s an incredibly powerful tool which is controlled by a very small few.
About six weeks ago, I made ZetaVM open source and announced it on this blog. This is a compiler/VM project that I had been quietly working on for about 18 months. The project now has 273 stars on GitHub. This is both exciting and scary, because so much of what I want to do with this project is not yet built. I really want to show this project to people, but I also find myself scared that people may come, see how immature/incomplete the project is at this stage, and never come back. In any case the project is open source now, and I think it would be good for me to write about it and explain some of the design ideas behind it, if only to document it for current and potential future collaborators.
One of the main goals of ZetaVM is to be very approachable, and enable more people to create their own programming languages, or to experiment with language design. With that goal in mind, I’ve designed a textual, stack-based bytecode format that resembles JSON, but allows for cycles (objects can reference one-another). Functions, basic blocks, and instructions in this bytecode format are all described as a graph of JS-like objects. This is very user-friendly. Anyone can write a Python script that outputs code in this format and run the output in ZetaVM. It’s also very powerful, in a LISP-y code-is-data kind of way: you can generate and introspect bytecode at run time, it’s just made of plain objects and values that the VM can manipulate. ZetaVM has first-class bytecode.
The downside of all this, as you can imagine, is that it inherently has to be absolutely dog slow. Or does it? The first version of the Zeta interpreter traversed the graph of bytecode objects the naive way, and it was indeed dog slow. I’ve since written a new interpreter which removes the overhead of the object-based bytecode by dynamically translating it to an internal representation (think dynamic binary translation). The internal IR is compact and flat, executing it involves no pointer hopping.
The new interpreter generates code on the fly, which means it is, by definition, a Just-In-Time (JIT) compiler. It’s architecture is based on Basic Block Versioning (BBV), a compilation technique I developed during my PhD (talks and papers on the topic are linked here if you’re curious). BBV has the nice property that it generates code lazily, and the generated code naturally ends up compact and fairly linear. This is not done yet, but BBV also makes it possible to specialize code to eliminate dynamic type checks very effectively, and to perform various optimizations on the fly.
You might be wondering why I’m bothering with an interpreter, instead of just writing a JIT that generates machine code. One of the motivating factors is that Zeta is still at a very early stage, and I think that an interpreter is a better choice for prototyping things. Another factor is that it occurred to me that I could potentially make Zeta more portable by having the interpreter do much of the compilation and optimization work. The interpreter can do type-specialization, inlining and various code simplifications.
The interpreter will be designed in such a way that the internal IR it produces is optimized and in many ways very close to machine code. It should then be possible to add a thin JIT layer on top to generate actual machine code. The resulting JIT will hopefully be much simpler and easier to maintain than if one were compiling directly from the raw object-based bytecode format. Another benefit of this design is that all of the optimizations that the interpreter perform will not be tied in with the specifics of x86 or other architectures, they will remain portable.
At the moment, the new interpreter is at a point where it lazily compiles code into the flat internal format, but performs no other optimization. This was enough to get a 7x performance improvement over the naive interpreter, but the current system is still quite a bit below the performance level of the Python interpreter, and there is definite room for improvement. Some of the first optimizations I would like to introduce are the elimination of redundant branching instructions, and the use of inline caching to speed up function calls.
The elimination of redundant branches is fairly easy to do with BBV. Code is lazily compiled, and appended linearly into a buffer. When generating code for a branch, if the block we are jumping to is just about to be compiled, then the branch is redundant. BBV will naturally tend to generate code that flows linearly along hot code paths and branches out-of-line for infrequent code paths. That is, the default path often comes right next and requires no branching.
Inline caching is a classic technique that was pioneered by the Smalltalk and SELF VMs. It’s used, among other things, to eliminate dynamic property lookups when polymorphic function calls are performed (see this excellent blog post for more information). Currently, ZetaVM, when performing a function call, needs to read multiple properties on function objects. For instance, it needs to find out how many arguments the function has, and what is its entry basic block. These property lookups are dynamic, and relatively slow. The end result is that the call instruction is very slow compared to other instructions.
Most call instructions will end up always calling the same instruction. Hence, dynamic overhead on function calls can largely be eliminated by caching the identity of the function being called by a given call instruction. That is, one can cache the number of arguments and entry basic block associated with a function object the first time a call instruction is run, and then reuse this information when calling the function again, provided we keep calling the same function. This information will be cached in line, in the instruction stream, right after the call instruction opcode, hence the name inline caching. I anticipate that with inline caching, function calls in Zeta can be made several times faster.
ZetaVM, my new compiler project
Like many of you I’m sure, I’ve wanted to create my own programming language for a long time. I think it’s a common aspiration for many programmers, to create a language with all the features we love and none of the ones we hate. Our own “ultimate programming language”, created in our own image. What I’ve come to realize over time, however, is that I’m actually not quite sure what should go into my ultimate programming language. I have a lot of ideas, but they don’t necessarily fit into a coherent whole. It’s also the case that my ideas about what the “ultimate programming language” should be like keep changing as I gain more programming experience and get exposed to new ideas.
My PhD was in compiler design, and this is something I truly enjoy playing with. As such, I’ve decided that my next programming language project wouldn’t be a programming language per-se, but actually a compiler, a platform to create new programming languages. I’m doing this in part because I enjoy it, and it’s something I feel confident I’m good at, but also because I think I can build a platform that will make it much easier for myself and others to do programming language design and experimentation. ZetaVM is going to have, as one of its main design goals, to make creating new programming languages very accessible. It will make it possible for anyone who’s mastered a language such as Python to create a language of their own, in less than 2000 lines of code. Not only that, but ZetaVM will instantly make your language decently fast. It will have JIT optimizations suitable to languages such as Python/Lua/JavaScript, and will instantly give you fast objects, type-specialization, etc.
ZetaVM is a virtual machine for dynamic programming languages. It will provide native support dynamic typing and most common data types found in Python/Lua/JS/Ruby, such as strings, extensible objects, extensible arrays. What makes it particularly easy to get your own language running on this VM is that Zeta’s Intermediate Representation (IR) is representable as a textual format similar to JSON. This makes it fairly trivial for you to write, say, a Python parser for your new language, and generate Zeta IR in a textual format at the output. You don’t have to worry about implementing dynamic typing, or register allocation, or garbage collection, or arrays and objects, all of that is done for you. I’ve created a simple language called Plush (JS and Lua’s bastard child), which demonstrates how this can be done, and serves to help me bootstrap and test the system.
Beyond making it easy for myself and others to create programming languages, Zeta will be a platform for me to try some bold new ideas in the design space of programming languages and JIT compilers. I would like to try and tackle one of the biggest issues plaguing programming languages today, which is that of code rot. My goal is to eventually freeze the IR and APIs provided by Zeta, so that code that runs on Zeta today might have a chance of still working in 20 years, without any changes. This goal is ambitious, but I have some ideas which I believe might make it work.
Finally, one big disclaimer I should give is that Zeta is still a young and immature project. In its current state, Zeta is experimental and will have many breaking changes, as most new languages/platforms do. Zeta also currently only has a naive interpreter which walks the object-based IR and is dog slow, about 200K instructions per second. I’m currently working on an interpreter that will compile the object-based IR into a lower-level internal IR. This interpreter will use Basic Block Versioning (BBV) and self-modifying code. I believe it should realistically able to reach speeds of 100MIPS within the coming months. My plan after that is to build a lightweight JIT which will sit on top of the optimizing interpreter and compile the internal IR to machine code.
The year is 2048. Migration to IP-V6 has just been completed. Every object in the world, including your coffee mug and the chair you’re sitting on, comprises a manycore RISC-V cluster, running Linux, with its own unique IP address. Haskell, because of its mathematically provable superiority, has come to supplant every other programming language. Writing code in any language other than Haskell is now a misdemeanor, punishable by up to 64 days of bandwidth throttling and a fine of up to 0.125BTC.
Wouldn’t things be much simpler if every computer system was built on the platform, ran the same operating system, and every program was written in the same programming language? I think that in many ways, this is the wet dream of many programmers. No more dealing with cross-language boundaries, portability issues, and multiple incompatible implementations of subpar standards. Things could be much simpler and more efficient than they are now.
The biggest problem, however, is that in a world where every computer system runs the same software, the same version of the same operating system, on the same hardware, every computer system has exactly the same bugs and security weaknesses. Given that some security flaw exists, a single computer virus could potentially contaminate every computer system in the world in a very short amount of time. In today’s world, this Hollywood-like doomsday scenario seems extremely implausible. The real world is too messy, or too diverse, for it to be practical to build a single virus or worm that could infect every system.
In a lot of ways, the chaos of the technological world resembles that of nature. Like animal species competing for survival, various technologies and standards compete for funding and mindshare. In nature, species specialize to exploit new environments. Diversity, in the technological world, exists in part because specialization makes systems more efficient, which allows the exploitation of new market niches. In nature, genetic diversity, or biodiversity, makes it near-impossible for a single virus to wipe out the entirety of life on earth.
Today’s technological world is definitely messy, but we can take comfort in the fact that competition really does foster innovation. The technological diversity that exists right now is a sign that we live in a thriving ecosystem, as opposed to one that is stagnant. With self-driving cars and a variety of home automation devices on the horizon, we can also take comfort in the idea that technodiversity may actually be keeping us safe.
Typed vs Untyped Virtual Machines
Minimalism in Programming Language Design
Democracy, Dictatorships and Access to Information
Code that Doesn’t Rot
The Internet Changed My Life
What’s Could You Use Tesla Bot For?
NoiseCraft: a Browser-Based Visual Programming Language for Sound & Music
Art Artificial Intelligence Artificial Life Assembly Biology Compilers Creativity D Language Electronics Future Game Development Genetic Algorithms Grad studies Graphics Higgs JavaScript Microcontrollers Microprocessors Music Programming Programming Languages Psychology Rant Robotics Tachyon Technology Uncategorized work x86 Zeta
Archives Select Month June 2022  (1) May 2022  (1) March 2022  (1) February 2022  (2) January 2022  (2) December 2021  (1) June 2021  (1) February 2021  (2) December 2020  (1) September 2020  (1) January 2020  (1) November 2019  (2) October 2019  (2) June 2019  (1) January 2019  (1) December 2018  (1) May 2018  (2) February 2018  (1) January 2018  (1) December 2017  (1) October 2017  (1) June 2017  (1) April 2017  (1) January 2017  (1) December 2016  (1) November 2016  (2) September 2016  (2) May 2016  (1) March 2016  (1) February 2016  (2) January 2016  (1) November 2015  (4) October 2015  (1) September 2015  (3) August 2015  (2) July 2015  (3) June 2015  (1) May 2015  (3) April 2015  (2) March 2015  (1) February 2015  (1) December 2014  (1) November 2014  (2) October 2014  (2) September 2014  (3) July 2014  (3) May 2014  (1) April 2014  (1) March 2014  (1) February 2014  (1) January 2014  (3) December 2013  (3) October 2013  (2) September 2013  (1) August 2013  (2) July 2013  (3) June 2013  (2) May 2013  (3) March 2013  (2) February 2013  (1) January 2013  (3) December 2012  (4) November 2012  (1) October 2012  (1) September 2012  (3) July 2012  (4) June 2012  (2) May 2012  (2) April 2012  (4) March 2012  (2) February 2012  (3) January 2012  (6) December 2011  (2) November 2011  (3) October 2011  (8) September 2011  (4) August 2011  (3)