725 karma · joined September 3, 2011
- Arch Linux
- just systemd/networkd for DHCP server/client, wireguard setup etc.
- router: own setup, just nftables, wireguard
- unbound DNS server (with blocklist for spam/ad domains) with encrypted DNS on uplink
- chronyd as timeserver
- mosquitto mqtt server
- custom jobs to post system stats to influx
- few VMs for testing things
- syncthing for keeping keepass database and documents
- git server (gitolite, gitc web)
- backup to encrypted S3 storage (duplicacy, encfs)
Hetzner VM
- influxdb (host stats, plus temp/humudity sensors around the house)
- grafana
If there are no conflicts, you might as well rebase or cherry-pick. If there is any kind of conflict, you are making code changes in the merge commit itself to resolve it. Developer end up fixing additional issues in the merge commit instead of actual commits.
If you use merge to sync two branches continously, you completely lose track of what changes were done on the branch and which where done on the mainline.
Programmers without a mathematical background will naturally struggle with such concepts. You can't point to where in the the code "the monad" is, as it's just the pattern, or the abstract mathematical combination of the type and the operations. Sure you could pack them into a class or a module, but it's still hard to point to where "the monad" is.
When we describe other patterns, like a Singleton, Factory, an Adapter, etc., it's is much more clear what and where the thing is. It's just a word to describe a function, a class, or a module.
Perhaps 'function composition with metainformation' would be a better title for the pattern. You take composable functions that act on certain types, and extend them to support metainformation attached to the values, while defining how the metainformation combines.
Kids don't like broccoli because they haven't tasted broccoli.