HN user

Kranar

5,476 karma
Posts0
Comments1,565
View on HN
No posts found.

This is untrue, algorithms measure time complexity classes based on specific operations, for example comparison algorithms are cited as typically O(n * log(n)) but this refers to the number of comparisons irrespective of what the complexity of memory accesses is. For example it's possible that comparing two values to each other has time complexity of O(2^N) in which case sorting such a data structure would be impractical, and yet it would still be the case that the sorting algorithm itself has a time complexity of O(N log(N)) because time complexity is with respect to some given set of operations.

Another common scenario where this comes up and actually results in a great deal of confusion and misconceptions are hash maps, which are said to have a time complexity of O(1), but that does not mean that if you actually benchmark the performance of a hash map with respect to its size, that the graph will be flat or asymptotically approaches a constant value. Larger hash maps are slower to access than smaller hash maps because the O(1) isn't intended to be a claim about the overall performance of the hash map as a whole, but rather a claim about the average number of probe operations needed to lookup a value.

In fact, in the absolute purest form of time complexity analysis, where the operations involved are literally the transitions of a Turing machine, memory access is not assumed to be O(1) but rather O(n).

People said the same thing about so many other online services since the 90s. The issue is that you're imagining ChatGPT as it exists right now with your current use case but just with ads inserted into their product. That's not really how these things go... instead OpenAI will wait until their product becomes so ingrained in everyday usage that you can't just decide to stop using them. It is possible, although not certain, that their product becomes ubiquitous and using LLMs someway somehow just becomes a normal way of doing your job, or using your computer, or performing menial and ordinary tasks. Using an LLM will be like using email, or using Google maps, or some other common tool we don't think much of.

That's when services start to insert ads into their product.

It's a common misconception that std::shared_ptr is thread safe. The counter is thread safe, but the actual shared_ptr itself can not be shared across multiple threads.

There is now atomic_shared_ptr which is thread safe.

Rules changed in 2003, but until then medical residency programs routinely had doctors working 100+ hours a week or longer. In 2003 a cap of 80 hours a week was instituted along with a maximum of 24 hours in any given period, but programs found various loopholes around that cap which still had doctors working close to 100 hours a week. So further restrictions were placed so that over any 4 week period there's a hard cap of 320 hours, no exceptions.

At any rate, for most of the HN crowd who work a fairly routine IT or an office job, 80+ hours sustained for months and months might seem impossible, but join the military, work on a ship, work on a farm, work the oil fields, work in investment banking, work in a film crew which threatened to go on strike in 2021 for having 98 hour work weeks for months on end... and you find that while it's not common, it certainly happens in various fields.

If only it were so easy as writing more makes you a better writer!

One commonly repeated piece of advice that almost all successful authors state is to write a lot, a lot, a lot. Like just practice writing, it doesn't have to be good.

I hear this often said about many other creative endeavors as well, including painting, cooking, game development/design, etc... It often seems like really good artisans just pull greatness out of thin air, but that's because we often only see the successes, not the failures, but I am reminded that even the best writers, poets, and artists in general spend a great amount of time just creating content that no one will ever see.

You can compute a number that is equal to BB(n), but you can't prove that it is the right number you are looking for.

You can't categorically declare that something is unprovable. You can simply state that within some formal theory a proposition is independent, but you can't state that a proposition is independent of all possibly formal theories.

That's a misinterpretation of what the article says. There is no actual bound in principle to what can be computed. There is a fairly practical bound which is likely BB(10) for all intents and purposes, but in principle there is no finite value of n for which BB(n) is somehow mathematically unknowable.

ZFC is not some God given axiomatic system, it just happens to be one that mathematicians in a very niche domain have settled on because almost all problems under investigation can be captured by it. Most working mathematicians don't really concern themselves with it one way or another, almost no mathematical proofs actually reference ZFC, and with respect to busy beavers, it's not at all uncommon to extend ZFC with even more powerful axioms such as large cardinality axioms in order to investigate them.

Anyhow, just want to dispel a common misconception that comes up that somehow there is a limit in principle to what the largest BB(n) is that can be computed. There are practical limits for sure, but there is no limit in principle.

This is true in general for every mathematical proof in ZFC (and even in more powerful theories). The decision problem "Given a formula F and an integer n, is there a ZFC proof of F of length <= n?" is NP complete, meaning that verifying the proof can be done in polynomial time while deriving the proof can require an exponential amount of time.

Plenty of companies have gone bankrupt or lost a great deal of credibility due to a single bug or single failure. I don't see why CrowdStrike would be any different in this regard.

The number of bugs/failures is not a meaningful metric, it's the significance of that failure that matters, and in the case of CrowdStrike that single failure was such a catastrophe that any claims they make should be scrutinized.

The fact that we can not scrutinize their claim in this instance since the details are not public makes this allegation very weak and worth being very skeptical over.

It's not a problem here as it has nothing to do with this to begin with. I am pointing out a limitation in a feature that the author has presented, but that feature does not resolve anything about the topic being discussed.

The goal isn't to allow a new type to work for an existing implementation of a function nor is it to take an existing type and write a new function that works with it. In the proposed solution you have `some_function` and the author claims that this solves the expression problem because you can take a new type C and pass it into some_function. Pretty much every language has a way to define new types and pass them into existing functions.

The goal is to allow for that new type, C, to have its own implementation of `some_function` that is particular to C, as well as the ability to write new functions that can be specialized for existing types. In particular we want calls to `some_function` through an interface to call C's specific implementation when the runtime type of an object resolves to C, and calls whatever other implementations exist when called through another interface.

The author's solution doesn't do that, it literally does nothing that you can't do in pretty much any other language.

While this has nothing to do with the expression problem, it's worth noting that in any case your solution does not work in general.

Rust does let you impl traits for types or traits that are inside of your crate, so your example strictly speaking works, but it does not let you impl traits if both the type and the trait are not inside of your crate. This is known as the orphan rule:

https://doc.rust-lang.org/reference/items/implementations.ht...

As the article points out, the expression problem itself is pretty simple to solve for code that you control, it's when writing modular software that can vary independently that gives rise to issues.

I don't understand what problem the author is trying to solve here - maybe it's language specific? More related to dynamic typing and efficient dispatch?

The expression problem only arises in statically typed programming languages, it does not exist in dynamically typed programming languages.

Operating overloading has nothing to do with the problem and can not be used to resolve it. Operators are nothing more than a one-off syntax so we can use familiar childhood notation like a + b, etc... they are not particularly meaningful. The ability to overload operators or functions in general is also irrelevant since such overloads are resolved statically at compile time.

Nothing you mention is related to this article and neither Rust or C# solve the expression problem.

The expression problem is about being able to extend both data types (new cases) and operations (new functions) without modifying existing code while preserving static type safety.

C#'s extension methods can't be virtual, so you can't use them to actually add any new operations which can be dispatched on. They're just syntactic sugar for adding static methods which in non-OOP languages can be accomplished by declaring a free function.

Rust traits let you add new types (just impl the Trait), but it doesn't let you add new functions, so it doesn't do anything to solve the problem.