Work

July 2023 month notes

I’ve been playing around with the V language which describes itself as an evolution of Go. This means letting go of some unnecessary devotion to imperative programming by allowing first-order map and filter as well as using an option syntax for handling errors. The result is quite an interesting language that feels more modern and less quirky than Go but isn’t quite as full on as Rust. I’ve enjoyed my initial experience but I haven’t been doing that much in it so far.

I’ve been continuing to experiment with Deno as well and I’m continuing to enjoy it as a development experience but I’m going to have to start doing some web development with it soon because while it’s fine for doing some exploratory programming using Javascript for command-line and IO stuff is not great, even with async/await.

I’ve been re-reading Domain Driven Design by Eric Evans. I’d forgotten how radical this book was. The strict tiering and separation of the domain model from other kinds of code is quite inspiringly strict. I wanted to try and have an abstracted business logic implementation in my last business where I was leading development but we never really got there as it was hard to go back and remove the historical complecting.

I’ve been doing some shell scripting recently and using some new (to me) commands in addition to old faithful’s like sed; tr transforms its input string to its output parameter making it easier to replace full stops or spaces with hyphens.

I’ve been trying a new shell wezterm after years of using Terminator. The appeal of wezterm is that it is cross-platform so I can use the same key-strokes across OSX and Linux. Learning new keybindings is always difficult but I’ve had no complaint about reliability and performance so far.

It was OKR time this month something I haven’t done in a while. OKRs are far more popular than they are useful. They seem to work best in mature profitable businesses than are seeking to create ambitious plans around sustaining innovation. Smaller, early-stage businesses still benefit from the objective alignment process but probably should still be focused on learning and experimenting in the Lean Startup model. As part of this process I was also introduced to Opportunity Solution Trees which in theory should have squared the circle on this problem but in practice the two systems didn’t mesh. I think that was because the company OKRs were generated separately from the Solution Tree so the activity in support of the objectives wasn’t driven by the solutions and experiments but were generated in response to the company objectives.

Standard
Programming

Cognitive bias and the difficulty of evolving strongly typed solutions

Functional Exchange 2013 featured an interesting talk by Paul Dale that had been mostly gutted but had a helpful introduction to cognitive bias. That reminded me of something I was trying to articulate about in my own talk when I was talking about the difficulty of evolving typed solutions. I used the analogy of the big ball of mud where small incremental changes to the model of the system result in an increasing warped codebase. Ultimately you need someone to come along and rationalise the changes or you end up with something that is ultimately too difficult to work with and is re-built.

This of course is an example of anchoring where the initial type design for the system tends to remain no matter how far the domain and problem have moved from the initial circumstances of their creation.

Redesigning the type definition of a program is also expensive in terms of having to create a new mental model of what is happening rather than just adapting the existing one. Generally it is easier to adapt and incorporate an exception or set of exceptions to the existing model rather than recreating an entire system.

Dynamic or data-driven systems are more sympathetic to the adaptive approach. However they too have their limits, special cases need to be abstracted periodically and holistic data objects can bloat out of control into documents that are dragging the whole world along with them.

Type-based solutions on the other hand need to be periodically re-engineered and the difficulty is that the whole set of type definitions need to be worked on at the same time. Refactoring patterns of object-orientated code often focus on reorganisation that is easy, such as pulling out traits or extracting new structures. This is still anchoring on the original solution though.

If a type system is to be help rather than a hindrance you need to be rework the overall structure. I think with most type-systems this is actually impossible. Hence the pattern of recreating the application if you want to take a different approach.

The best typed solution currently seems to be type unions where you can make substantial changes and abstractions but not have to work about things like type hierarchies or accidentally polluting the edge cases of the system.

Where these aren’t available then good strongly-typed solutions actually rely heavily on good, proactive technical leaders to regularly drive good change through the system and manage the consequences.

Standard
Programming

Why Repositories and not Services?

This is a good question. Why do people like ThoughtWorks make a lot of fuss about things like Services but then want to use things like the Repository pattern when writing code?

The short answer is that Service Orientation and Domain Driven Design have two slightly different concerns.

For example, in a transportation domain you don’t get a Truck from a Truck Service you get a Truck from the Garage or the Truck Manufacturer depending on whether you own it or are buying it. The point being that a Truck Service in Domain Design terms is meaningless, it is just something that programmers introduce to make their code easier for them to use.

If however you want to track where a Consignment is then it makes sense to offer this as a service. For a start it has different audiences; I might want to offer tracking to customers via the web and a slightly more detailed version of the service to the Customer Service Department.

In this sense the Tracking Service is actually a Domain item, people actually talk about the Tracking Service and the Service has been organised around the transactions and expectations that happen in the course of transporting goods.

I am not sure if it makes any sense to talk about a Service in your codebase if it does not have an external consumer for its functionality. Usually Service objects that only interact with your own code can be broken up and have their concerns divided in a different way so as to eliminate them. A Truck Finder for example might make sense, it would handle finding out whether a Truck was on the Road, in the Depot or in the Repair Shop. The Depot might then tell you whether the Truck was being loaded while the Truck could tell you how full it currently was.

Once you have identified external consumers for a service then you get into the question of Service Contracts and a lot of the good things about Service Architectures begin to apply. Limiting concerns, platform neutrality and service composition for example; but this involves a lot more than just tacking the word “Service” on the end of a class.

Standard