I generally try to limit the total amount of extensions I have on my browser, to a list of tools I feel that I can trust. I apply the same mentality for dependencies in my software. Limits the surface area for supply chain attacks.
731 karma · joined August 11, 2023
I generally try to limit the total amount of extensions I have on my browser, to a list of tools I feel that I can trust. I apply the same mentality for dependencies in my software. Limits the surface area for supply chain attacks.
I use this strategy on a lot of sites (which sadly includes stackoverflow lately).
I think a lot of people here are conflating mono-repo/poly-repo with a mono-deployment. You can easily add in extra entrypoint executables to a single mono-repo. That allows initiating parts of the system on different machines, allowing scaling for skewed API rates across your different request handlers.
Similarly, you can create a monolith application building from a poly-repo set of dependencies. This can be easier depending on you version control system, as I find git starts to perform really poorly when you enter multi-million SLOC.
At my job we have a custom build system for poly-repos that analyzes dependencies and rebuilds higher level leaf packages for lower level changes. Failing a dependency rebuild gets your version rejected, keeping the overall set of packages green.
As the project progressed we started adding more in Kotlin and it massively improved developer experience.
Always try to ask myself when adding tooling: What's the chance I'll want to remove this later, and how painful is that going to be?
That'll be really helpful for nested method calls which proxy a lot of their arguments along. I can also see that helping out when creating stub libraries.
I would honestly be perfectly happy with a black screen for 30 seconds as a compromise to ads. I only leave the twitch webpage because the visuals bother me almost just as much as hearing the stupid sales pitch or the goofy "lol we're so cheeky and random" jokes made non-stop by insurance company ads.
Still, I can understand it for some components like loggers to not add boiler plate to every library. However, I was very uneasy to see that enabling gzip decompression in a gRPC server is done through a magic _ import. You have to initialize the server anyways, so why not just make it an explicit function argument?
Apart from just Ads, I use the "Block Element" feature of uBlock to cut down on a lot of other visual noise within sites. For youtube I block the giant rows of "related" video suggestions (which I guess you could consider as ads), and youtube shorts from showing up in my subscription feed.
The later fits nicely into the `Function<,>` interface, `Function<T, Result<R, Err>>` vs the former requires a different interface entirely, something like `FuncE<T, R, Err>` where `Err` breaks out into an argument for the throws value of the signature.
Because most of the functional libraries in Java work with Function, BiFunction, etc, we end up with incompatible arguments for common patterns such as `map`, `filter`, etc.
I’ve always heard that we painted the houses with whatever paint was on hand because the wind is strong that it strips away every couple of years. And we’re not a rich group of people, so whatever paint you have is the right paint!
My grandfather used to remark on the houses “they were crap when the went up, but somehow lasted 50 years, so I guess they’re heritage now”.
But, they do look pretty in the summer!
Especially painful when using any of the functional style stream operations, like `map`, `filter`, etc, or any other higher order function library. Most take in the standard `Function` or `BiFunction` interface arguments, which will not support method referencing for anything which includes a checked exception as part of its signature.
I think this actually speaks well to the point of the article. We can simplify the logic a lot by using boring tech, in this case, separating the query builder logic from the connection/transaction logic. Switching from one very complex ORM, to two more understandable simple systems, and getting back to more grass roots with querying.
As for validating your software, the answer is the same as its always been… tests, tests and more tests.
F = TypeVar(“F”, bound=Callable)
def wrapper(f: F) -> F: …