This is the second post in a series on designing software for weavers. These posts contain random thoughts and musings based on design challenges that I come across as I build a real-world project. In the first post I give the context for this project and presented the code for a initial domain-driven design. In this post and the next one, we’ll move to the next stage, converting between a text representation and the domain model.
This post is part of the 2025 F# Advent Calendar. Check out all the other great posts there! And special thanks to Sergey Tihon for organizing this.
Recently, I have taken up a new hobby, hand weaving. As a meditative, physical activity with tangible results, it’s a great antidote to doom-scrolling and spending too much time in front of a screen. The first time I tried it, something about the weaving process really appealed to me and I got a little bit obsessed with learning more.
In the first post in this series, we came up with some properties that could be used to test a run-length encoding implementation:
The output must contain all the characters from the input, in the same order Two adjacent characters in the output cannot be the same The sum of the run lengths in the output must equal the total length of the input If the input is reversed, the output must also be reversed In the previous post, we tested various RLE implementations created by the Enterprise Developer From Hell and were happy that they all failed.
In the previous post we attempted to define some properties for a run-length encoding (RLE) implementation, but got stuck because the random values being generated by FsCheck were not very useful.
In this post we’ll look at a couple of ways of generating “interesting” inputs, and how to observe them so that we can be sure that they are indeed interesting.
Observing the generated data The first thing we should do is add some kind of monitoring to see how many of the inputs are interesting.
In a previous series of posts, I introduced you to the burned-out and lazy programmer known as the Enterprise Developer From Hell, or the EDFH for short. As we saw, the EDFH loves to practice malicious compliance.
Recently, the EDFH’s influence was apparent with this viral answer to an interview problem.
Write a function that converts the input to the output.
Input: “aaaabbbcca” Output: [(‘a’,4), (‘b’,3), (‘c’,2), (‘a’,1)]
Of course the EDFH answer is simple:
In this series, we looked at six different approaches to dependency injection.
In the first post, we looked at “dependency retention” (inlining the dependencies) and “dependency rejection”, or keeping I/O at the edges of your implementation. In the second post, we looked at injecting dependencies using standard function parameters. In the third post, we looked at dependency handling using classic OO-style dependency injection and the FP equivalent: the Reader monad.
In this series, we are looking at six different approaches to dependency injection.
In the first post, we looked at “dependency retention” (inlining the dependencies) and “dependency rejection” (keeping I/O at the edges of your implementation). In the second post, we looked at injecting dependencies using standard function parameters. In the third post, we looked at dependency handling using classic OO-style dependency injection and the FP equivalent: the Reader monad.
In this series, we are looking at six different approaches to dependency injection.
In the first post, we looked at “dependency retention” (inlining the dependencies) and “dependency rejection” (keeping I/O at the edges of your implementation). In the second post, we looked at injecting dependencies as standard function parameters. In this post, we’ll look at dependency handling using classic OO-style dependency injection and the FP equivalent: the Reader monad Revisiting the logging problem In the previous post, I briefly discussed the logging problem.
In this series, we are looking at six different approaches to dependency injection.
In the first post, we looked at “dependency retention” (inlining the dependencies) and “dependency rejection” (keeping I/O at the edges of your implementation). In this post, we’ll look at “dependency parameterization” as a way of managing dependencies. Dependency parameterization Given that you have made the effort to separate pure from impure code, you may still need to manage other dependencies.
This post is part of the 2020 F# Advent Calendar. Check out all the other great posts there! And special thanks to Sergey Tihon for organizing this.
In this series of posts, we’ll look at six different approaches to doing “dependency injection”.
This post was inspired by Mark Seemann’s similar series of posts, and covers the same ideas in a slightly different way. There are other good posts on this topic by Bartosz Sypytkowski and Carsten König.