222 karma · joined July 28, 2012
DB queues allow easy prioritization, blocking, canceling, and other dynamic queued job controls that basic FIFO queues do not. These are all things that add contention to the queue operations. Keep your queues as dumb as you possibly can and go with FIFO if you can get away with it, but DB queues aren't the worst design choice.
Across all startups, yes they can be risky and there will be innovative outliers that take off. But for a single no-name startup a misstep can be a death knell.
https://fsharpforfunandprofit.com/posts/designing-with-types...
https://ybogomolov.me/making-illegal-states-unrepresentable/
In practice, I find it is usually something like 'UnvalidatedCustomerInfo' being parsed into a 'CustomerInfo' object, where you can validate all of the fields at the same time (phone number, age, non-null name etc.). Once you have parsed it into the internal 'CustomerInfo' type - you don't need to keep re-validating the expected invariants everywhere this type is used. There was a good video on this that I wish I could find again, where the presenter gave the example of using String for a telephoneNumber field instead of a dedicated type. Any code that used the telephoneNumber field would have to re-parse and validate it "to be safe" it was in the expected format.
The topic of having untrusted external types and internal trusted types is also explained in the book `Domain Modeling Made Functional` which I highly recommend.
Personally, I lean towards the "use nulls sparingly and be very explicit where null values are possible", use immutable objects etc. This reduces the unnecessary null-check noise and makes things more robust. In java, I even prefer to add @Nullable to fields to try to switch the default mindset to "assume non-null unless @Nullable annotation exists" - though another developer made a note on a code review that "that is not how Java is designed and @Nullable is just noise".
Having nullability as part of the type makes everything more explicit, so I'm a huge fan. Beyond just the perf and safety benefits, it's a win for domain modeling.
- Elixir (and Erlang) https://elixir-lang.org/
- Akka - JVM and .NET frameworks - https://akka.io/ https://getakka.net/
- Actix - Rust framework - https://actix.rs/docs/actix/getting-started
- MS Orleans - https://learn.microsoft.com/en-us/dotnet/orleans/overview
- Pony - https://www.ponylang.io/
[0] https://learn.microsoft.com/en-us/dotnet/architecture/micros...
- https://fly.io/blog/introducing-litefs/
- https://fly.io/blog/all-in-on-sqlite-litestream/
This allows for extremely cheap s3 database backups as well as fast local serving layer.
And many more deep dives on their blog - https://fly.io/blog/
Libraries _can_ hide some of this, but then that might also be yet another function or operator that does the same thing. Internalizing when to use one method vs. another adds to the total cognitive load of using the language, and it takes away from the mental capacity available for the problem you are actually trying to solve.
Sometimes these differences are necessary and important, other times they are less so.
If you're really interested in this stuff, it has been an ongoing centerpiece in Matt Levine's newsletter. Articles are free if you subscribe to the email, but reading prior pieces may require a subscription. e.g. https://news.bloomberglaw.com/securities-law/matt-levines-mo...
[1] https://elizarov.medium.com/types-are-moving-to-the-right-22...
There was a Changelog podcast episode with Richard Hipp (sqlite author) where he threw out the great idea that it would be nice if there were renderers in popular markdown engines that could display inline pikchr blocks. https://changelog.com/podcast/454
More examples of what is possible are on the linked pikchr page: https://pikchr.org/home/doc/trunk/doc/examples.md
Integrating with Java's existing build systems (Gradle, Maven) was one of JetBrains initial design goals to avoid the separate ecosystem requirement that initially came with Scala. I admit building Kotlin has some quirks, notably around annotation processors - but overall it is very seamless.
I am happy Java is adding new stuff (records, switch expressions, sealed classes), but I worry it is increasing overall language complexity vs. the fresh start that Kotlin was able to take. Supporting the legacy patterns in the language adds to the complexity any given Java developer is supposed to know.
Overall I think the sane defaults and nudges towards the right patterns Kotlin pushes are a much bigger deal than just reducing boilerplate - though that is nice too.
https://zig.news/kristoff/struct-of-arrays-soa-in-zig-easy-i...
My experience is a micro-scale observation that it did not take much campaigning to convince developers to try it (given the existing level of support backed by Jetbrains).