Timeline from the article sounds a lot like a logical clock, which is a well known primitive in distributed systems: https://en.wikipedia.org/wiki/Logical_clock
HN user
znkr
You mean like driving a car?
We put asterisks next to proofs that use the axiom of choice. If a machine comes up with proof that’s not verifiable by humans, you can very well be sure that there will be asterisks.
+1 The worst code I had to maintain was code that tried to follow DRY (without the trying to understand what the original intention of that principle was). The only way out of that mess was widespread code duplication.
It makes even less sense in an era of LLMs.
I would argue that out makes even more sense in the era of LLMs. LLM shaped tasks are tasks that we would hand out to junior engineers. Now, I can implement one of these tasks in 1hr instead of waiting for a junior engineer to finish this in 1-3 days. This means the equation for investing in junior engineers has shifted towards disfavoring investment.
Moving running computers around and maintaining connection would have required large trucks and very long cables at the time the internet was invented.
If a project in an unsafe language has ever had a memory bug (I'm looking at you, Bun), the maintainers objectively have a track record of not being capable of manual memory management. You wouldn't put a person who has a track record of crashing busses at the wheel of a school bus.
If you’re serious, you should stop using Rust (which happens to contain an unsafe language): https://github.com/rust-lang/rust/issues/44800
LISP ;-)
I am sure they have this. What tends to happen is that the gradual rollout system becomes too slow for some rare, low latency rollout requirements, so a config system is introduced that fulfills the requirements. For example, let’s say you have a gradual rollout for binaries (slow) and configuration (fast). Over time, the fast rollout of the configuration system will cause outages, so it’s slowed down. Then a requirement pops up for which the config system is too slow and someone identifies a global system with no gradual rollout (e.g. a database) to be used as the solution. That solution will be compliant with all the processes that have been introduced to the letter, because so far nobody has thought of using a single database row for global configuration yet. Add new processes whenever this happens and at some point everything will be too slow and taking on more risk becomes necessary to stay competitive. So processes are adjusted. Repeat forever.
Maybe it helps to think of matrix multiplication as a special case of the composition of linear transformation. In the finite dimensional case they can be expressed as matrix multiplications.
The whole article starts with the implicit assumption that all bases are orthonormal and then throws linear algebra out of the window completely.
Bismarck was afraid of workers unionizing and transformed a working healthcare system owned by workers into a state owned one. That move significantly reduced the utility of worker unions, which was the goal behind it.
I don’t think it’s a wordplay with the r-word, but rather a reference to the famous Shakespeare quote: “Hoist with his own petard”. It’s become an English proverb. (A petard is a smallish bomb)
Search for memory wall. Moore’s law died a decade ago for DRAM
I actually used the examples from that paper for testing. The results that they are showing in the paper are different from mine and I think that git changed as well. I believe the conclusions from that paper no longer hold.
Good point, thanks!
One use case where I never want to miss it is in tests: Understanding what the differences between the expectation and the actual result are is invaluable.
A minimal diff is one where the number of edits is minimal. The context around edited lines does not count as edits, because they are matching lines. That said, minimal is definitely only a proxy, that’s why is a good property to relax.
Even if something does align better with real numbers, it's still just x+0i
Beware, it’s not always useful to work in complex numbers, you sometimes want to do something different for reals and complex numbers. The prime example here is complex analysis. Defining differentiation is based on limits, on the complex plane there are a lot more directions to approach a limit vs just two on the real line. This has some interesting implications. For example, any function differentiable on the complex plane is infinitely differentiable.
The equal sign should be reserved for comparisons, because that is what it means in mathematics.
This is touching on a pet peeve of mine: Mathematics and programming are similar in many aspects, but this is not one of them. In mathematics = is not a comparison, but a statement.
More generally, mathematics is about tautologies, that is statements that are always true. In programming, a comparison is evaluated to either true or false.
That doesn’t mean that there’s no room for conditionals in mathematics (one example is piecewise function definitions). But it’s not the same. Heck, even the definition of “function” is different between mathematics and programming.
I agree, this is a real benefit of RAII compared to defer. That said, there are disadvantages of making the resource freeing part invisible. Not having to debug destructors that do network IO (e.g. closing a buffered writer that writes to the other side of the world) or expensive computation (e.g. buffered IO writing to a compressor) is a define plus. Don’t get me started on error handling…
When I switched from C++ to a bunch of other languages, I missed RAII initially. However, I quickly learned that other languages just do it differently and often even better (ever had to check an error when closing a resource?). Nowadays, I think that RAII is a solution to a C++ problem and other languages have a better solution for resource management (try-with-resources in Java, defer in Go, with in Python).
It’s mostly fine, until you run into memory leaks due to circles or because some part of your program holds onto the root of some large shared pointer graph and you have no idea which part. If you take it very far, like some code bases I worked with did, you discover that everything needs to be shared pointer now, because most lifetimes are no longer explicit but implicitly defined by the life time of the shared pointer that holds it.
I used to program a lot in C++ but switched to a number of different programming languages since then. Everything in C++ is this way and it’s hard to understand that things don’t have to be this way when you’re in the trenches of C++.
Not a guru, but my take is that the actor model is one method of architecting a system to separate synchronization from other concerns. There are other ways to do that, often specific to a particular problem and with more or less separation. As always, there are many tradeoffs involved.
Go has a couple of SIMD uses. Copies is one of them.
No, it was based on Google+ which was integrated with Picasa
You would have that frustration anyway during toolchain upgrades if the map implementation changed from one go version to the next.
I have been writing Go code for many years, the fact that I don’t need to think about things unrelated to the problem I am trying to solve is why I love Go. I definitely learned a lot about Go and I am thinking more about certain aspects than before, but usually only in the context of API design.