/pages /computing

December Adventure

The December Adventure is low key. The goal is to write a little bit of code every day in December.

December Adventure 2023

The Goal: learn more about the /hare programming language and double-entry bookkeeping by tinkering on a command-line based accounting program called books.

It would be great if I ended up with a prototype of a working personal budget tool, and if I was able to introduce myself to the Hare community and make some contributions.

/december-adventure Stream

December 6, 2023

/stream /programming /december-adventure

Today's work was thinking work. Part of my goal of putting the /coalescent computer on pause was to start framing coalescent data within existing computing systems instead of a blank slate, and so I wanted this project to reflect that. Today I was thinking about how I would manage the different "resources" (accounts, entries, reports) in a coalescent way, and I think I came up with a plan to achieve that.

Each "agent" (user/node pair) will have its own event log, and each log can only be edited by its owner. A log is just a text file where each line describes some (CRUD) event on a resource. The logs can freely be synced with other agents, and each agent can keep track of how long it thinks each log is so that they know when there are new events to process in a given log. If my state tells me that agent1.log is 40 lines long, but my local copy is now 42 lines long, that means two events have come in for that log since the last time I processed events.

Effectively, this means the CLI will have some commands that write to the local agent's event log, an event log resolver that generates and modifies resources based on all of the event logs as a single logical unit, and then report generating commands that work from the local resources. There can be a little bit of state on an agent that helps it track and cache what it's already computed, but it can also at any point just re-run through all of the event logs again to rebuild the current state. Playing back events means it will also be possible to catch instances where new events are trying to write to "closed" books.

This sounds complicated when writing it all down, but I think with a little more planning it should be possible for this to be implemented pretty quickly (minus syncing, which will just be done with rsync).

December 5, 2023

/stream /programming /hare /december-adventure

Another short December Adventure session today, but I implemented some functionality for creating and listing accounts within a project. For now, this is done by adding files to an 'accounts' directory inside the project, and having each account file be the stringified version of an account struct. I should probably put together some kind of de/serializing functions that make it easier to re-ingest the text file back into program data later on, and also clean up the way I'm creating "resources" since I'll need to do a lot more of that. Honestly, if I have more than a few minutes to work on this tomorrow I should take a step back and do a bit more planning now that I have all of this infrastructure working.

December 4, 2023

/stream /programming /hare /december-adventure

I only had about twenty minutes for my December Adventure today, but managed to implement the books list command using the config work from yesterday. I also refactored those config functions to work as a general key-value store, which made it very easy to then also implement books set project to set the active project. Overall, the work I did yesterday made it so that implementing these other commands was pretty straightforward. I need to come back to this a bit later and think through the error handling a bit better, because for now it just unwraps all the errors with !.

$ ./books list
$ ./books set project home

December 3, 2023

/stream /programming /hare /december-adventure

Had a pretty packed day, but found a few moments to tinker. Spent most of today's time starting to learn about the fs, io, and os modules of the standard library. Wrote a few functions for reading and writing files, and now the CLI for books lets you set a directory where it looks for your projects by default. Trying to lean on the filesystem to do all of the work in this project, so this "setting" is just a file $XDG_CONFIG_HOME/books/root that contains the path.

$ ./books set root ~/books
$ cat ~/.config/books/root

December 2, 2023

/stream /programming /hare /december-adventure

Today's work on the December Adventure was more fleshing out of the command tree as I was thinking about the different types of resources that need to be created and managed. Things like accounts, journal entries, and so on. Fleshing out the tree has been a good test of my cli module, and is also a good way to think through the use of the program as a set of resources being managed.

I also needed to figure out a way to have the user set an active project and let the program know where to find project directories, and this led me to learn about the XDG Base Directory Specification, which is what defines the ~/.local, ~/.config, and ~/.cache directories, and what types of files should go in each. I learned something new, and also figured out how I should handle the default storage of configuration and state data for this program.

December 1, 2023

/stream /programming /hare /december-adventure

I've been cutting my teeth on /hare for a few weeks now, and yesterday I finally got my "learning project" (a CLI argument parsing module) finished. So today, I started work on a CLI double-entry bookkeeping program which I think is going to be my December Adventure for 2023.

Today's work was fleshing out a command tree using my new argument parsing module, and then learning about how the Hare compiler uses multiple source files. I can now compile a binary that executes a few placeholder subcommands.