Recent submissions

Comment · 18 days ago
As we know from physics, even the most sophisticated mechanisms (e.g. friction) often ends up having a very simple model (proportional to the normal force).

Sooo, the score is maybe mostly just how much they fit?

Comment · 26 days ago
LeanStore found a very elegant solution to this: https://dl.acm.org/doi/abs/10.1145/3596225.3596228

They don’t actually free the memory, but rather put it back into the memory pool with an incremented version counter. It can later be re-used as a new node, the version counter _not_ being reset.

In LeanStore’s use case they either way have a fixed amount of memory they’d like to use (since it’s a page buffer on top of disk data) so there’s no actual need to give the memory back to the OS.

If you’d like to actually free the memory back it’s a lot easier since you can now treat this more of an infrequent operation. The cost of that will be amortized very well.

EDIT: They also describe another very cool idea: If the memory is allocated with mmap you can deallocate it by using madvise DONT_NEED. This will cause the version counter to be “0” which you can interpret as “invalid”. You can then deallocate it at a later point when you’re absolutely sure no threads could access it. You’re basically doing a two-stage deallocation where the first stage releases the memory, but the page information is kept until the second stage.

Comment · 2 months ago
I'm confused. How is this simpler? Is there something in (-1)^(2x) that can easily understood by staring at the complex plane? It seems mostly that you've gotten rid of "e", but one of the goals of Euler's formula IMO is to explain what "e^(i …)" means so I'm not sure how this variant is useful.
Comment · 2 months ago
In the initial state there's 24 (12 * 2) different possibilities: The marble you're looking for is one of 12 and it's either lighter or heavier. By using a balance scale there's 3 possible outcomes (left side is heavier; right side is heavier; same weight). This means that for your last (third) weighing you'll have to have reduced the problem down to 3 (or fewer) different possibilities. If there's 4 or more there's no way to reduce it down to a single possibility. Before the second weighing you should have reduced it down to 9 (3*3) different possibilities.

Once you know this, you can start making educated guesses for the first weighing and quickly eliminate those which makes it impossible to continue. For instance: Splitting the marbles into two. This gives two possible outcomes: Left side is heaver or right side is heavier. For the first outcome it means that either the target marble is lighter and part of the left group (6 marbles) or heavier and part of the right group (6 marbles). That's 12 different possibilities (more than 9) and therefore we know that it's impossible to determine the marble with just two more weighings.

There's still guessing to be done, but at every part of the decision tree you can at the very least quickly avoid exploring paths which are guaranteed to not work.

Comment · 3 months ago
I imagined that I'm 24 years old and I have a 20 years old brother. When I were his age, he would have been 16 years old.

I also realized that this can be expressed in terms of a two pairs of sibling:

> Mary and Ann are the same age difference as Jane and Claire. Mary is 24 years old. Mary is twice as old as Jane. Claire is as old as Ann. How old is Ann?

This highlights also why it's so confusing:

> Mary is 24 years old. She [Mary, today] is twice as old as Ann was [Ann, past] when Mary was [Mary, past] as old as Ann is [Ann, today] now. How old is Ann?

In one sentence we're comparing past and present ages.

Comment · 3 months ago
Rephrasing it makes it easier to grasp:

Mary is 24 years old. When Mary was Ann’s current age, Ann was 12 years old (half Mary’s current age).

This makes it a bit easier to realize that Ann’s age has to be right in the middle of 12 and 24.

Comment · 3 months ago
Comment · 4 months ago
Not sure where I picked up this, but I’ve added this to my global Git ignore:

    attic
That way you can just create an attic directory in any project where you can keep random stuff that should never be committed. I’ve yet to find a repo which actually has such a directory checker in.
Comment · 6 months ago
Ignoring the misuse of epsilon, I'd also say that you'd be helping your users more by not providing a general `assert_f64_eq` macro, but rather force the user to decide the error model. Add a required "precision" parameter as an enum with different modes:

    // Precise matching:
    assert_f64_eq!(a, 0.1, Steps(2))
    // same as: assert!(a == 0.1.next_down().next_down())

    // Number of digits (after period) that are matching:
    assert_f64_eq!(a, 0.1, Digits(5))

    // Relative error:
    assert_f64_eq!(a, 0.1, Rel(0.5))
Comment · 7 months ago
This is just wrong. See https://en.cppreference.com/w/cpp/atomic/memory_order.html. Emphasis mine:

> A store operation with this memory order performs the release operation: no reads or writes in the current thread can be reordered after this store. All writes in the current thread are visible in other threads that acquire the same atomic variable (see Release-Acquire ordering below) and writes that carry a dependency into the atomic variable become visible in other threads that consume the same atomic (see Release-Consume ordering below).

Comment · 8 months ago
It’s just an encrypted file on disk. You’d depend on whatever backup solution you already have in place.
Comment · 10 months ago
Very cool project! Always happy to see more work around static analysis.

However, looking at the recent commits it doesn't quite look like the most solid foundation: https://github.com/shuaimu/rusty-cpp/commit/480491121ef9efec...

    fn is_interior_mutability_type(type_name: &str) -> bool {
        type_name.starts_with("rusty::Cell<") ||
        type_name.starts_with("Cell<") ||
        type_name.starts_with("rusty::RefCell<") ||
        type_name.starts_with("RefCell<") ||
        // Also check for std::atomic which has interior mutability
        type_name.starts_with("std::atomic<") ||
        type_name.starts_with("atomic<")
    }
… which then 30 minutes later is being removed again because it turns out to be completely dead code: https://github.com/shuaimu/rusty-cpp/commit/84aae5eff72bb450...

There's also quite a lot of dead code. All of these warnings are around unused variable, functions, structs, fields:

    warning: `rusty-cpp` (bin "rusty-cpp-checker") generated 90 warnings (44 duplicates)
Comment · 10 months ago
Can you show an actual minimal C program which has this problem? I’m trying to follow along here, but it’s very hard for me to understand the exact scenario you’re talking about.
Comment · 10 months ago
Is there a specific reason to store the key + value as an `uint64_t` instead of just using a struct like this?

    struct slot {
      uint32_t key;
      uint32_t value;
    }
Comment · 10 months ago
> If a carpenter shows up to put a roof yet their hammer or nail-gun can't actually put in nails, who'd you blame; the tool, the toolmaker or the carpenter?

I would be unhappy with the carpenter, yes. But if the toolmaker was constantly over-promising (lying?), lobbying with governments, pushing their tools into the hands of carpenters, never taking responsibility, then I would also criticize the toolmaker. It’s also a toolmaker’s responsibility to be honest about what the tool should be used for.

I think it’s a bit too simplistic to say «AI is not the problem» with the current state of the industry.

Live from the official Hacker News API

A modern reader for Hacker News · SvelteKit + Skeleton