typedef struct foo foo;
and somewhere else
struct foo { … }
1,475 karma · joined February 13, 2025
typedef struct foo foo;
and somewhere else
struct foo { … }
A: participate and have a chance to not be part of a perpetual underclass
B: for moral reasons, don't participate, be part of the underclass
I kinda would have hoped for
C: <something> to stop this from happening
Otherwise it's the worst sales-pitch ever
Auth is a building block you can slot into your system and the shape of the hole isn't all that complex. A framework is something you need to slot your system into, and it has a lot of twists and turns so it ends up restricting how you do all the other things.
There are lots of microservice-foundation-related building blocks. E.g. I use a library somewhere that just does circuit-breaking. I slot that into my app rather than the other way around, and if I wanted to replace it, it's a fairly isolated thing. I don't use any frameworks for it though
Frameworks also tend to grow more and more complex as they evolve. If I as a user want a different auth for example, that needs to be supported by the framework. Over time, all things become pluggable and configurable, until at some point it's complex enough that someone restarts the process, or makes an opinionated spin of the framework.
Would it have been nice if the Date object had been immutable? Sure, but the fact that changing the mutable object does indeed change the object shouldn't be a shock
Rhetoric and persuation has long been studied by humanity, but that doesn't make NLP real
The second best advice is probably, do just c with classes. Allow defining your own allocator to make objects of those classes. It's fine if objects built with one allocator can only refer to objects built by the same one.
Don't do templates, just do the minimum needed for a container type to know what type it contains, for compile time type checking. If you want to build a function that works on all numbers regardless if they are floats or complex or whatever, don't, or make it work on those classes and interfaces you just invented. A Float is a Number, as is an Integer. Put all that cleverness you'd waste on templates into making the compiler somewhat OK at turning that into machine types.
Very specifically don't make the most prominent use of operator overloading a hack to repurpose the binary left shift operator to mean `write to stream`. People will see that and do the worst things imaginable, and feel good about themselves for being so clever.
They did add some optional sections like bounds checking that seem to have flopped, partly for being optional, partly for being half-baked. Having optional sections in general seems like a bad idea.
Front page says "zero logs"
Some logs, including specifically datapoints you have promised not to log, but you mean well (?) is pretty different from zero logs
Also:
> // What we DON'T collect:
> - IP addresses (not logged, not stored, not tracked)
> - Usage patterns (no analytics, no telemetry, nothing)
> - Device fingerprints (your browser, your business)
so, I've read one blog from this company, and already they're lying or incompetent
It was a while since I used arduino, but I remember having a harder time setting up a workflow that didn't need me to touch the arduino IDE.
The process of getting a binary onto the board is just dragging a file, and on linux at least you can script it with picotool
As soon as you add users you need to start coping with backwards compatibility though, even if your backend is still a monolith.
The backend being a monolith is probably easier for a while yes, but I've also lost count of the number of companies I've been to who have been in the painful process of breaking apart their monolith, because it doesn't scale and is hard to work with
Microservices or SOA aren't trivial, but the problems you bring up as extremely hard are pretty easy to deal with once you know how; and it buys you independent deploys and scale, which are pretty useful things at a bigger place
Scale
Both in people, and in "how do we make this service handle the load". A monolith is easy if you have few developers and not a lot of load.
With more developers it gets hard as they start affecting eachother across this monolith.
With more load it gets difficult as the usage profile of a backend server becomes very varied and performance issues hard to even find. What looks like a performance loss in one area might just be another unrelated part of the monolith eating your resources,
This is much less of a problem than it seems.
You can use a serialisation format that allows easy backward compatible additions. The new service that has a new feature adds a field for it. The old client, responsibly coded, gracefully ignores the field it doesn't understand.
You can version the API to allow for breaking changes, and serve old clients old responses, and new clients newer responses. This is a bit of work to start and sometimes overkill, given the first point
If you only need very rare breaking changes, you can deploy new-version-tolerant clients first, then when that's fully done, deploy the new-version service. It's a bit of faff, but if it's very rare and internal, it's often easier than implementing full versioning.