When you do a hack (or even a dirty hack) you do it for some reason. You do it because you can understand the complexity of the problem and you see it’s a complex problem to solve that needs a good enough solution for your case.
You are facing the complexity. You are seeing it. You are seeing the deepness of the abyss.
This project started a little bit like an exercise to do that. Take a simple problem: make a Gopher client, and try to solve it in a decent way collecting information during the process.
It’s just a learning project, but it went wild.
The initial idea was to force myself to use Clojure’s network API, which is Java’s one, because I never used it in the past and I wanted to learn about it and the possible problems it can have. In order to do that I decided to write a Gopher client, because that way I’d also had to read the RFC and some resources more.
I sketched the Gopher protocol exchange without many problems, because it’s quite simple and the RFC is really well explained. The wild part came with the rest of the project, which still is under heavy development and it doesn’t work yet (this sentence may be edited in the future, I hope it will).
I wanted to make a terminal based client, and I had a cool library for this,
called clojure-lanterna
which is just an interface to lanterna
, a java
library for TUI (Terminal User Interfaces). When I wanted to use
clojure-lanterna
I realized the project was kind of abandoned and it didn’t
cover the UI elements, only the basic screen interface, and I decided to make
it by myself.
Further than that, I thought that if I focused on only POSIX compatible
operating systems I wouldn’t need to use lanterna
neither. So I decided to
implement everything by myself.
That took me to some thoughts I’ve been having these days: When software has few dependencies or no dependencies at all you have more control over the process of making it. People who code in popular programming languages have even more libraries than we need and it’s really hard to stop the temptation to use them (this explains some recent events with NPM repositories, for instance). This is not only about security –possible security breaches in libraries we use– or control –the fact that we included some software we don’t know– it’s also about remembering that libraries can’t be software you just import: they should be read, analysed and, often, thrown away in favor of an ad-hoc solution. Many times ad-hoc solutions reduce the codebase size and they solve the problem more accurately, as they are specifically design to solve our problem.1
Also, it’s good to tell yourself you can code everything from scratch and try to prove it true.
In summary, I wanted a project that covered these points:
- Be a simple Gopher client.
- Written in Clojure.
- Terminal User Interface (TUI).
- No dependencies if possible.
And all of them had some sense, at least in my mind, on the early beginning of the project.
So, here we are
As I said before, the goal is not to create a good software. It’s not even to create something that works. The idea is to learn during the process and this post series is a way to put what I learned in an ordered way.
If you follow this post series, you’ll follow me on my research and hacks. We are going to dive on all those weird concepts that will appear. I’ll try to be as technically correct as I can but I’m not an expert and this is not a class. I’m just sharing my experiences.
I’m looking at the abyss and telling you what I see from this view, pointing the interesting things I spot.
-
As a note, while I was writing this, I experienced some issues with nested dependencies in a different piece of software I was using. Dependencies can be understood as a tree, with your project at the root. More deep the tree is, longer time for changes to arrive the root of the tree from the leaves, because changes must be accepted in all the nodes of the affected branch and developers are busy. This can be a problem like in the case I experienced where a bug in a leave of the tree was solved but the root was broken and was unable to solve the issue because they needed an intermediate node to update the version of the leave. This hurts.
(They should’ve never added the change in the first place but when dependencies go deep it’s more difficult to detect bugs) ↩