Bei der Diskussion um erneuerbare Energien ist es immer gut einige Fakten und Größenordnungen vor Augen zu haben. Insbesondere sind Meldungen in der Presse immer einordnungsbedürftig. Ist ein Jubelartikel zum Windpark mit 10MW zum Jubeln? Nein ist er nicht. Eine einzelne Windkraftanlage hat schon zwischen 5 und 18MW (Frühjahr 2023).
Everyone seems to be using software frameworks these days and each has its own hype-culture, uniqness-claim, and provides an in-group for its followers. Being somewhat distrustful by nature I developed an aversion against software frameworks over the years. To be a bit more specific, I had to work with Spring, Spring Boot, Angular, Gradle and Reactor. So what I say below is inspired by those and may or may not apply to others.
I make a difference between a software framework and software library. Though the border is a bit blurry, a library is roughly a software framework without all the ugly stuff I mention below.
I contrast this all with a software library providing a well designed API. There is no magic, behaviour is invoked explicitly by calling into the API. Getting started is slightly harder, because some boilerplate code needs to be written to invoke the needed API functionality in the right order. Yet often the boilerplate is not as boilerplate as framework designers assume. There are always those quirky deviations from the assumed and enforced "standard" which force you to fight against framework magic, while the not-quite-boilerplate code you have to write when using a library is all yours to adapt to your needs.
In addition, when leaving a project alone for half a year and coming back, the boilerplate makes explicit what is going on. It can by understood easily again. With a framework, things, hopefully, just happen and you might have forgotten some of the magic details you had researched — until they stop to work or you need to change something.
Using a framework, you literally sell your soul and bet the future of your software on that one framework, since switching would require a complete rewrite. Call it vendor lock-in if you want. But not only with regards to your software. Also with regards to your knowledge and experience. The experience you gather comprises a lot of how to fight or subvert the framework magic to get it your way, not their assumed default way.
In contrast, with a well designed library API, chances are that the next best library covering a similar topic has a similar API. You learn how to use the API, not how to fight against off-by-epsilon magic behaviour. Switching your software to a similar library may actually be possible, while switching away from or to another framework is typically a 100% rewrite.
$$\Mset(k,i) := \{kn -i \,|\, n\in\NN\} \quad\text{ for } k\in\NN \text{ and } 0\leq i\lt k.$$
So $\Mset(5,4) = \{1, 6, 11, \dots\}$. For convenience lets define
$$\DD = \{\Mset(k,i) \,|\, k\in\NN \land 0\leq i\lt k\}.$$
With union over the shifts $i$ we get the natural numbers:
$$\NN = \bigcup_{i=0}^{k-1} \Mset(k,i).$$
But what happens with the intersection of two set of $\DD$?
Proposition: For two set $A, B\in\DD$ we have either $ A\cap B = \emptyset$ or $A\cap B \in \DD$.
Proof: Suppose $A = \Mset(k,i)$ and $B=\Mset(l,j)$ are not disjoint. Then let $s$ be the smallest element in $ A\cap B$. By definition of $A$ and $B$ we can find $n_k, n_l\in\NN$ such that
$$ s = kn_k -i = ln_l -j \qquad \text{with } i,j\in\NN. $$ Let $q = \lcm(k, l)$ be the least common multiple of $k$ and $l$. Then we can find $0\leq r \lt q$ and $t\in\NN$ such that $s = qt - r$. Namely chose $t = \lfloor\frac{s}{q}\rfloor + 1$ and $r = s - tq$.
Assume that $t>1$. Then define $s_0 = q - r \lt s$ and we have
\begin{align*} s - s_0 &= qt - r -(q -r)\\ &= q(t-1)\\ \text{or}\qquad s_0 &= s - q(t-1) \end{align*}
Since $q=\lcm(k,l)$ we can write $q=q_kk=q_ll$ for some $q_k, q_l\in\NN$ and so we get
\begin{align*} s_0 &= s - q_kk(t-1) &&= s - q_ll(t-1)\\ &= kn_k -i - q_kk(t-1) &&= ln_l -j - q_ll(t-1)\\ &= k(n_k -q_kk(t-1)) -i &&= l(n_l -q_ll(t-1)) -j\\ \end{align*} This shows that $s_0\in \Mset(k,i)\cap\Mset(l,j)$ though $s$ was defined to be the smallest of those. Therefore we have actually $s=s_0= q-r$.
We now show that $A\cap B = \Mset(q,r)$.
Backward direction: Let $t'\in\NN$ and define $s'=qt' - r\in\Mset(q,r)$. Then we have $$s'-s = qt'-r - (q-r) = q(t' -1).$$ Similar to the reasoning above it follows that
$$ \begin{align*} s' &= s + k q_k(t'-1) &&= s + l q_l(t'-1) \\ &= kn_k - i + k q_k(t'-1) &&= ln_l -j + l q_l(t'-1)\\ &= k(n_k+q_k(t'-1))-i &&= l(n_l+q_l(t'-1)) -j\\ \end{align*} $$ And since $t'-1\ge 0$ this shows that $s'\in A\cap B$.
Forward direction: Let $s'\in \Mset(k,i)\cap\Mset(l,j)$ so we have $$ s' = kn_k' - i = ln_l' -j. $$ It follows that \begin{align*} s'-s &= kn_k' - i - (kn_k-i)&&= ln_l' - j -(ln_l-j) \\ &= k(n_k'-n_k) && = l(n_l'-n_l) \end{align*} Consquently $s' -s$ is a multiple of both, $k$ and $l$, which means $q=\lcm(k,l)$ is a factor of $s' - s$, say $s'-s = q_sq$. But then we have
\begin{align*} s' &= s + q_sq\\ &= q - r + q_sq\\ &= q(q_s + 1) -r\\ & \in\Mset(q,r). \end{align*}