Programming projects in 2020
This is a post where I summarize some of the projects I have been hacking on during 2020. Note that only "non-work" related projects are covered by this list. FOSS projects which I have been able to contribute to during work time are included, though.
(The text below is an excerpt from my general page about programming which can be found here.)
-
2020: No university courses this year, only a fair amount of spare-time & work-time hacking was performed.
-
Perlang (133h) + CSLox (10h) + jlox (4h): At last, I couldn't resist it. I was probably already thinking about doing this, and then saw Bob Nystrom's great guide Crafting Interpreters being posted at Hackers News. Unsure about the exact post that got me triggered (there are multiple ones), but this one coincides pretty well with the timing when I started hacking on this (January 2020).
Oh, and before I forget it: Bob, I owe you a big one. Please let me know if you ever happen to visit the area where I live and I'll happily buy you a pizza.
Here is a rough timeline of events (and yes, documenting this mostly for myself):
-
January 3rd: I registered the
perlang.org
domain. I wrote in my diary this day that "it's not like there will be any code to put there within the next few years". I guess I still believed at this time that I would be able to refrain myself from starting the project. -
January 7th: started playing around with Perlang/
jlox
... I came to the conclusion that I'd better follow thejlox
guide to get a basic understanding of how compilers & interpreters function. -
January 17th-19th: I spent a bit of time between the 7th and the 17th as well, but a significant "spike" took place during this particular weekend. During it, I went on a journey to attend a family ceremony in Sweden, which meant there was quite some travel time, during which I first worked on my jlox implementation, and later the cslox one.
My version of
jlox
is pretty much a straightforward implementation of Bob's original (Java) interpreter as outlined in the book, with some minor changes (wrote a Ruby script for generating the AST classes instead of the original Java code).cslox
, on the other hand, is a rewrite of this code in C#. The reason I rewrote it in C# is obvious: since I intended to write Perlang in C#, it would be more useful for me to have the code for the Lox interpreter in C# than in Java.I continued hacking on
cslox
until about... -
January 26th: The day when the initial commit was made in the Perlang repo. Very cool, at least to me! The original commit wasn't really something that would impress anybody (it was just
.gitignore
and license file), but later the same day I added a commit that imported thecslox
code base, adjusted the namespaces etc. to make it a useful base to continue building on. The project was using .NET Core 3.1 at this point; .NET 5 was net yet released.I will not go on with describing all the rest of the year at this level of detail, but I want to mention some key events before we move on to the next project (yes, there are other ones as well )
- Jan 26: Added GitHub Actions config for automatically building the project in CI. CI is an incredibly important aspect for a project IMHO; we never want to merge in code which breaks the build (or doesn't pass all the unit/integration tests). We added this right from the start.
-
Feb 11: Added support for publishing builds on each
master
commit. The builds were originally published to Bintray, but was subsequently moved to https://builds.perlang.org - June 6: Implemented support for optional typing. This is an important feature that got added quite early. Perlang wants to be different from languages like Ruby, JavaScript and others which are "purely dynamical" in nature (parameter/variable types can not be specified using natural syntax in the language). In this sense, Perlang aims to more similar to languages like TypeScript, but the end-goal is even more advanced than that: we hope to eventually make Perlang be able to compile to (statically typed) MSIL byte code.
-
June 11: Added perlang-install script. This makes it possible to install (the
master
builds of) Perlang on your Linux/macOS/Windows machine quite easily. -
Sept 20: Added support for native classes + calling static methods in native classes. Perlang does not currently support OOP mechanisms like being able to declare classes, use inheritance etc., but what we do support is being able to call static methods like
Base64.encode()
(declared on theBase64
class). The global methods previously added asbase64_encode
andbase64_decode
was also refactored to take advantage of this functionality, to provide better structure and avoiding polluting the global namespace. - Sept 30: A pull request was merged which publishes a basic docfx-based web site at https://perlang.org. It's not really that fancy and there a lot of things missing, but still: if you're interested in the project and some of the "why's" behind the whole thing, it might still be worth giving this a look.
I'll readily admit: for now, the reason for doing this is largely as a fun hobby for myself. Some people collect postage stamps, or do woodworking, or bake really cool sourdough breads, or create their own keyboards based on DIY toolkits. I don't mean to degrade any of that. It's just not for me. I write integration tests for my compiler and add new functionality to my standard library instead...
-
January 3rd: I registered the
-
halleluja.nu (20h): Slightly overshadowed by the above project, my https://www.halleluja.nu preaching/ministry web site did receive at least some attention during the year. As if the above (Perlang) project wasn't enough, I was also bitten by another bug this year, namely: the "do-your-own-static-site-generator" bug. I think the work on
halleluja.nu
was mostly related to taking the new static-sitegen into usage, but I did write at least one sermon as well (in Swedish): Rättfärdighet, frid och glädje i den helige Ande(There is some English-language material on the site as well, and I'm hoping to add more at some point. The support for multiple languages was merged right around the end of 2020, so it's still very new at the time of writing.)
-
sitegen (13h): This is the "engine" that now empowers the www.halleluja.nu web site. I was a bit tired of Jekyll, e.g. related to the performance (which isn't that great, given that it's Ruby-based) and poor multi-language support (which depended on a plugin which I fixed a bug in). I started hacking on this after testing a few other approaches:
-
How about just using Hugo? I tried this approach but it would mean some work, learning the details about how Hugo works and so on. To be honest, I'm pretty tired of software. I work with programming all day (it's my day job, after all), and sometimes I just don't have the energy to learn about how other people's software work. Will I even be happy about it after learning it, or will there be aspects that annoys me? If so, the effort of learning it might feel like I have wasted my time.
In practice, I am somewhat more interested in learning a new library or toolkit or similar, than learning how to use someone else's ready-made software. Something which probably affects my feelings here as well: Hugo is written in Go. This is great for performance; Go is typically much more performant than your average Ruby tool. Still, Go is not a language that I'm familiar with.
And even if I were, I would still be forced into someone else's design decisions. For some of you, maybe this is fine. I don't know, I'm perhaps just stubborn enough to not be as easily pleased as the average person.
How about rolling my own in JavaScript, using EJS templates? I did start playing around with this a bit. There's just one major problem with it: I'm not a very big fan of JavaScript, and even TypeScript suffers from the limitation that it's "just JavaScript" under the hood. There are definitely nice aspects about this, but to me, the disadvantages (like dynamic typing) are too compelling for me. It's also an ecosystem I don't normally "live" in and is not interested in living in. Even though the EJS library I started using would take me a bit towards the end goal (being able to publish a static site based on dynamic templates + Markdown documents), I would still need to write a bit of glue code here and there and I concluded that I wouldn't be interested in this.
How about zola, would it work? (Answer: probably, but it's not as widely used as e.g. Jekyll or Hugo. I looked a bit at it, and even submitted a minor PR towards it. It is written in Rust, so in some ways, better than JavaScript. Then again, Rust isn't a language I am working with everyday, and I'm not incredibly productive in it. Also, again it would mean I have to learn someone else's software, hoping that it would support my (fairly specialized) needs. It may be that it could have worked well, but I decided to try another approach... again. This would now be the fourth approach I tried.
-
How about rolling my own, in C#, with Handlebars.net templates? This is where it started to become really interesting. I found out about the nice little Handlebars.Net library which I could use to write my templates using the Handlebars syntax. This was a critical thing I wanted to achieve, if I would go the route of doing my own site generator: instead of a highly opinionated system with lots of "conventions" and other fancy stuff, I wanted something which was basically "PHP/Ember.js", but pre-rendered as a bunch of static HTML files. Instead of layouts determining how things should be rendered, I wanted an
index.hbs
file that just{{include '_includes/header.hbs'}}
. In other words, going away from the "declarative approach" to the "imperative approach"."Why on earth would anyone want a static site generator that works like that", you might ask yourself. Of course, the answer is: it depends. If all you're doing is something pretty plain, a single-language web site, you're probably much better off with just using something fairly opinionated, like Jekyll. Or Hugo if you want something faster (and perhaps it's less opinionated). You learn the conventions, and once they are interned, you are happy.
But: in my case, I am off for something more complex. I want it to support multiple languages, without having to resort to ugly hacks (like the Jekyll plugin that currently empowers the https://perlun.eu.org web site). I'd also preferably like to be able to make cross-linking between languages work (so that URLs like
/sv/bibelstudier/1_mosebok/1
and/en/bible-study/genesis/1
can be logically connected). In other words: pretty custom logic in terms of how the site is structured. (I'm not even sure that particular use case with cross-linking of URLs between languages can be achieved without custom code in the actual C# engine, but anyway...)All-in-all, this led to the creation of sitegen. It supports the following features:
- Handlebars templates - giving you full control over the structure of your web site, as described above.
- Configuration using YAML
- Content authoring via static Markdown files
The tool is currently in a pre-0.1.0 shape, but... it's working, I am using it for the www.halleluja.nu web site since a few weeks back in production. It's poorly documented, doesn't have any unit tests and so on, but if your needs are similar to mine, feel free to try it out (and submit bug reports if you find issues with it). The best way to understand how it works is probably to study the source code for the halleluja.nu web site here: https://github.com/perlun/halleluja.nu
-
-
dotfiles (9h): My personal dotfiles got a bit of love during the year. One of the things I am happiest about is that I was able to convert base64_decode and base64_encode to Perlang, since I added stdlib functions in Perlang for doing base64-decoding & encoding. These are literally the first Perlang programs in the world, eating my own dog food as I ought.
Apart from this, a few improvements here and there. This is stuff I use on all the machines I use regularly (work desktop, work laptop, sometimes my home desktop etc), so it tends to get a bit of attention.
perlun.eu.org (5h): Not too much work was done apart from the https://perlun.eu.org/en/2020/01/05/programming-projects-in-2019 page.
UsageLogger (3h): Implemented a simple Vue+jQuery (yeah, I know) web interface and an ASP.NET MVC REST API endpoint for retrieving some stats, based on data which was already logged by the Windows background application.
chaos4ever.github.io (3h): I did a little effort to make the https://chaosdev.io work better on mobile devices, using some simple resonsive breakpoints. I liked this. Frontend development can actually be fun sometimes. :)
armeria (2h): Armeria is a microservice framework, which we use at work. I submitted a pull request, adding some documentation; this is one of the nice changes I did in the sense that I could actually do it as part of my regular day job. I wouldn't mind to spend more professional time working on free software; it would be nice to work full-time on these kinds of projects. Who knows, maybe one day.
.bash_completion.d (2h): Tab-completion in
bash
is something I find very valuable. Based on the the original fork by dysosmus and others, I added support for multiple inventory files and fixed a simple caching implementation of the completion data, to reduce the commandline latencies. (I hate high latencies.)ArchUnit (2h): Again, this is a project we use at work. In this case, to enforce architectural constraints for a code base (things like: "only classes in package 'foo' can use the 'Bar' class", "only class 'Baz' can use classes in package 'zot'", etc. Run this in your unit tests and execute them in CI, and you make it more or less impossible to break these kind of architectural conventions by mistake). I added a new
doNotBelongToAnyOf
static method to its DSL: https://github.com/TNG/ArchUnit/pull/422chaos (1h):
chaos
didn't receive a whole lot of love from me during 2020. I don't anticipate this to change at all during 2021. If I have time & energy for these kind of projects, I will focus on Perlang and halleluja.nu. Anything else will have to wait for some other time in my life; I consider it less important for the time being.Some other minor changes were submitted to various projects. For more details about all my GitHub contributions during the year, follow this link.
-