First, the slow part:
  • personal problems for the last two months -- life is hard
  • changing the type system is slightly harder than I originally thought
  • adding unit tests & refactoring along the way

There is little you can do for the first bullet point. Therefore, I'll focus on the other two bullet points.

Before starting the type system work, Sparrow had zero unit-tests. With this effort, I was convinced that we need unit-tests to make considerable progress in Sparrow. That took a lot of work, but it's starting to show signs that it pays off. I have now, some rough numbers that I can use to see if it pays off.

Previously, when I developed a more complex features, I encountered one or more road-blocks. I used to spend, let's say, 20 hours to avoid a road-block. Because of the complexity of the software, I didn't fully understand what the compiler is supposed to do, so I had a lot of wrong assumptions, and also there were a lot of bugs in the code. To overcome such a road-block, I typically had some kind of special-condition check that would fix the case I was working on, without affecting the already working functionality. But this is the worst thing that one can do: it just accumulates complexity, making it even harder to solve a problem next time.

With the new mindset, whenever I'm encountering a road-block, I refactor the code, and I unit test it. This costs me around 25 hours of work (very rough estimates). But after the refactoring & testing, I spend about 4 hours or less to avoid the road-block.

Doing the math yields a great advantage for refactoring & unit testing. I'll gain time each time I encounter 2 road-blocks in the same part of the code. Yes, it feels slower to refactor & add unit tests for everything, but in the grand scheme of things, it actually makes things faster.

I was able to see this slow/fast perspective with this feature. First, I spent a lot of time trying to avoid a road-block. Then, I go back and refactor the code. Then all the road-blocks can be easily overcome. I have unit-tests that will tell me each mistake I'm making.

I hope that, it won't be long until I have unit-tests for most of the compiler logic. Then, any change that I'm making will be much faster. And the good news is that I don't have to bite the costs all at once. I can write unit-tests while I'm working on different parts of the compiler. So far I have unit-tests for basic nodes logic, basic type logic, type conversion logic and Feather types. Right now I'm working on refactoring the SparrowFrontend nodes and unit-test the generics nodes.

May unit-tests keep you on the right path!