Hello, Fortran world!
program hello_world
implicit none(type, external)
print *, 'Hello, world!'
end program hello_world
Since January 2024 I’m working with a smart group of programmers at Deltares. They create and maintain software in the complex “business” domains of hydrodynamics, morphology, water quality and ecology. Their software is used to understand and predict all kinds of phenomena related to water, by which they “Enable Delta life”. And that’s not just for the Netherlands (many of us here live below sea level or close to rivers); the software is used around the world, by governments and businesses.
New edition for the Rector Book

A couple of weeks ago, Tomas Votruba emailed me saying that he just realized that we hadn’t published an update of the book we wrote together since December 2021. The book I’m talking about is “Rector - The Power of Automated Refactoring”. Two years have passed since we published the current version. Of course, we’re all very busy, but no time for excuses - this is a book about keeping projects up-to-date with almost no effort… We are meant to set an example here!
Dealing with technical debt during the sprint
It’s quite ironic that my most “popular” tweet has been posted while Twitter itself is in such a chaotic phase. It’s also quite ironic that I try to provide helpful suggestions for doing a better job as a programmer, yet such a bitter tweet ends up to be so popular.
Twitter and Mastodon are micro-blogging platforms. The problem with micro-blogs, and with short interactions in general, is that everybody can proceed to project onto your words whatever they like. So at some point I often feel the need to explain myself with more words, in an “actual” blog like this one.
Refactoring without tests should be fine
Refactoring without tests should be fine. Why is it not? When could it be safe?
From the cover of “Refactoring” by Martin Fowler:
Refactoring is a controlled technique for improving the design of an existing code base. Its essence is applying a series of small behavior-preserving transformations, each of which “too small to be worth doing”. However the cumulative effect of each of these transformations is quite significant.
Good design means it's easy-to-change
Software development seems to be about change: the business changes and we need to reflect those changes, so the requirements or specifications change, frameworks and libraries change, so we have to change our integrations with them, etc. Changing the code base accordingly is often quite painful, because we made it resistant to change in many ways.
Code that resists change
I find that not every developer notices the “pain level” of a change. As an example, I consider it very painful if I can’t rename a class, or change its namespace. One reason could be that some classes aren’t auto-loaded with Composer, but are still manually loaded with require
statements. Another reason could be that the framework expects the class to have a certain name, be in a certain namespace, and so on. This may be something you personally don’t consider painful, since you can avert the pain by simply not considering to rename or move classes.
Can we consider DateTimeImmutable a primitive type?
During a workshop we were discussing the concept of a Data Transfer Object (DTO). The main characteristic of a DTO is that it holds only primitive-type values (strings, integers, booleans), lists or maps of these values including “nested” DTOs. Not sure who came up with this idea, but I’m using it because it ensures that the DTO becomes a data structure that only enforces a schema (field names, the expected types, required fields, and optional fields), but doesn’t enforce semantics for any value put into it. That way it can be created from any data source, like submitted form values, CLI arguments, JSON, XML, Yaml, and so on. Using primitive values in a DTO makes it clear that the values are not validated. The DTO is just used to transfer or carry data from one layer to the next. A question that popped up during the workshop: can we consider DateTimeImmutable
a primitive-type value too? If so, can we use this type inside DTOs?
Is it a DTO or a Value Object?
A common misunderstanding in my workshops (well, whose fault is it then? ;)), is about the distinction between a DTO and a value object. And so I’ve been looking for a way to categorize these objects without mistake.
What’s a DTO and how do you recognize it?
A DTO is an object that holds primitive data (strings, booleans, floats, nulls, arrays of these things). It defines the schema of this data by explicitly declaring the names of the fields and their types. It can only guarantee that all the data is there, simply by relying on the strictness of the programming language: if a constructor has a required parameter of type string
, you have to pass a string, or you can’t even instantiate the object. However, a DTO does not provide any guarantee that the values actually make sense from a business perspective. Strings could be empty, integers could be negative, etc.
A step-debugger for the PHP AST
When you’re learning to write custom rules for PHPStan or Rector, you’ll have to learn more about the PHP programming language as well. To be more precise, about the way the interpreter parses PHP code. The result of parsing PHP code is a tree of nodes which represents the structure of the code, e.g. you’ll have a Class definition node, a Method definition node, and within those method Statement nodes, and so on. Each node can be checked for errors (with PHPStan), or automatically refactored in some way (with Rector).
Simple Solutions 1 - Active Record versus Data Mapper
Having discussed different aspects of simplicity in programming solutions, let’s start with the first topic that should be scrutinized regarding their simplicity: persisting model objects. As you may know, we have competing solutions which fall into two categories: they will follow either the Active Record (AR) or the Data Mapper pattern (DM) (as described in Martin Fowler’s “Patterns of Enterprise Application Architecture”, abbrev. PoEAA).
Active record
How do we recognize the AR pattern? It’s when you instantiate a model object and then call save()
on it:
What's a simple solution?
“As I’m becoming a more experienced programmer, I tend to prefer simple solutions.” Or something similar. As is the case with many programming-related quotes, this is somewhat of a blanket statement because who doesn’t prefer simple solutions? To make it a powerful statement again, you’d have to explain what a simple solution is, and how you distinguish it from not-so-simple solutions. So the million-dollar question is “What is a simple solution?”, and I’ll answer it now.