Adam James

September 17, 2021

Areas For Improvement on My Next Project

nice-work.png

I wanted to write down, as a short post, some things I noticed while working through my last coding project. Though it was successfully completed and I'm proud of the work on RSS-Saver, there are some bits of the process and the final product that I am not totally pleased with. Writing about them here serves as a way for me to acknowledge areas where I can still improve.

I imagine this effort to be similar to watching back a video of yourself doing squats at the gym. You did the work and pushed the weight, but it's important to check that your form is OK. It's helpful to observe where tiny optimizations can be made, to avoid issues in the future and feel encouraged to keep focusing on what you're doing. 

It's a bit of self-coaching.

Speed

Not every project needs to be done quickly, but this was quite small and probably could have been built much more quickly. I hope that for similar scripts in the future (ingest something, parse it, transform it, export it) I'll be able to finish things in a day or two.

I also spent far too long adjusting the web version of the code. I found myself getting frustrated with differences between my Clojure and Clojurescript environments. As I keep building web content I think I'll build up intuition and experience with handling the strange differences, but it's a source of friction at the moment. I think I have to consider how valuable an interactive blog post might actually be for any given code; if I could re-do things, I would likely skip the interactive version of RSS-Saver. As a general rule, I should prefer interactive posts that have (or would greatly benefit from) clear, interactive visuals (SVG stuff for example), or can clarify complex functionality within a project.

I think I should spend more time thinking about the data structures I want to define in a project and the transforms that need to be applied to them to get my desired outcome. That is, I should spend a bit more time defining the full data flow/pipeline within my design docs before I start implementing. If I'm very clear on the data structure and the needed transforms, I can really improve my 'implementing speed' with practice. And the more projects I do, the more patterns I'll start to see and internalize, ultimately having a positive effect on implementation speeds. 

In general, I want to spend more time thinking and planning the structure of the project before I implement. That will prevent re-work and reduce the times where I implement something that I ultimately delete entirely.

Tests

I still need to be better at writing tests. Not every function needs tests, but tricky parts of my projects often don't have enough tests to show the intended behaviour. I still too often write tests after the fact, not during the main programming session. I'll need to pay attention to integration testing too, as only unit testing probably won't cover everything.

I also want to get better at using more thorough testing methods like generative testing, and should learn Malli and/or spec to help write better specifications for data structures in my work.

For the RSS-Saver script, I also worked around the fact that I was invoking the code as a script by tangling two versions of the code: rss-saver.clj, and rss-saver-tests.clj. This works well using org-mode's Noweb, as I didn't actually write implementations twice, but I think there's a cleaner way to write tests that other Clojure developers will understand better.

Literate Style

I still love writing programs in .org files, and think there's real value to this approach. However, I don't always use org-mode to its full potential. Specifically, I don't always write enough about the code and my thought process as I'm coding. Instead, I often go back later and try to clarify my thoughts with some prose. I would prefer, instead, to write more up front before I write code blocks, and just go back and edit the prose later for clarity.

I should really improve my Emacs settings too. Particularly, when I hit an error, I don't have good context as the line and column numbers reported are for the tangled source, not the org file's line numbers. There may be a way to add some middleware to CIDER, but I don't yet know how to solve this one.

I want to think further on how to optimize my workflow to allow the best features of literate programming and org-mode to work well with modern Clojure tooling like clj-kondo, Paredit, autocomplete, etc. Oliver Caldwell's Conjure is a very inspiring setup that I want to study and either emulate or adopt, with my own special literate-style twist.

Distribution

Small scripts don't really need anything more than a clear set of install and usage instructions in the readme, but I want to have a clearer picture for distribution and deployment of my projects in the future. I'm generally keen on building small binaries for CLI tools and desktop apps, so should become comfortable with GraalVM and its native-image tool.

Releasing should also have a sensible versioning story. I don't know if SemVer is a good idea. I suspect not really. But I don't have a good idea myself other than literally incrementing an integer after every meaningful push, where 'meaningful' is some set of edits to the code that result in a usable state of the program. That is, for working features and bug fixes, basically.

Support

If you want to support my work, you can provide a one time donation here:
https://ko-fi.com/adamjames

Or you can become a Patron of mine here:
https://www.patreon.com/adam_james

Support is never required by me, and anything I write or produce publicly (not explicitly as a paid product) is always free to consume with no obligation or expectation. I want to be a maker and a creator, and much of the time sharing work is reward enough. 

At the same time, we live in a world where money is very important, and I won't lie and say I don't need some. If you feel so inclined to share a donation, just know that I am extremely grateful.