<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Hacker News: moefh</title><link>https://news.ycombinator.com/user?id=moefh</link><description>Hacker News RSS</description><docs>https://hnrss.org/</docs><generator>hnrss v2.1.1</generator><lastBuildDate>Thu, 30 Apr 2026 00:31:00 +0000</lastBuildDate><atom:link href="https://hnrss.org/user?id=moefh" rel="self" type="application/rss+xml"></atom:link><item><title><![CDATA[New comment by moefh in "Floating point from scratch: Hard Mode"]]></title><description><![CDATA[
<p>Nice write-up.<p>Let me offer a nitpck: in the "Gradual underflow" section it says this about subnormal numbers:<p><pre><code>    Bonus: we have now acquired extra armour against a division by zero:

    if ( x != y ) z = 1.0 / ( x - y );
</code></pre>
But that's not that useful: just because you're not dividing by zero doesn't mean the result won't overflow to infinity, which is what you get when you <i>do</i> divide by zero.<p>Think about it this way: the smallest subnormal double is on the order of 10^-324, but the largest double is on the order of 10^308. If `x - y` is smaller than 10^-308, `1.0 / (x - y)` will be larger than 10^308, which can't be represented and must overflow to infinity.<p>This C program demonstrates this:<p><pre><code>    #include <stdio.h>
    #include <float.h>
    #include <math.h>

    // return a (subnormal) number that results in zero when divided by 2:
    double calc_tiny(void)
    {
        double x = DBL_MIN; // the normal number closest to 0.0
        while (1) {
            double next = x / 2.0;
            if (next == 0.0) {
                return x;
            }
            x = next;
        }
    }

    int main(void)
    {
        double y = calc_tiny();
        double x = 2.0 * y;
        if (x != y) {
            double z = 1.0 / (x - y);
            printf("division is safe: %g\n", z);
        } else {
            printf("refusing to divide by zero\n");
        }
    }
</code></pre>
(It will print something like "division is safe: inf", or however else your libc prints infinity)</p>
]]></description><pubDate>Tue, 07 Apr 2026 15:37:27 +0000</pubDate><link>https://news.ycombinator.com/item?id=47677005</link><dc:creator>moefh</dc:creator><comments>https://news.ycombinator.com/item?id=47677005</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47677005</guid></item><item><title><![CDATA[New comment by moefh in "A tail-call interpreter in (nightly) Rust"]]></title><description><![CDATA[
<p>Yes, I agree. Like I said, it <i>might</i> be useful when dealing with something that is easier to express in (tail) recursion form instead of an iteration.<p>Anyway, here's something more-or-less equivalent in Rust, which will blow the stack if made to loop too many times: <a href="https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=42d597503ef128d8e79cfbb1a466b129" rel="nofollow">https://play.rust-lang.org/?version=stable&mode=debug&editio...</a><p>(There may be a way to use a closure instead of a function to avoid hard-coding the type of `$i` in the macro, but I can't find an easy way to write a recursive closure call in Rust).</p>
]]></description><pubDate>Mon, 06 Apr 2026 17:51:49 +0000</pubDate><link>https://news.ycombinator.com/item?id=47664379</link><dc:creator>moefh</dc:creator><comments>https://news.ycombinator.com/item?id=47664379</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47664379</guid></item><item><title><![CDATA[New comment by moefh in "A tail-call interpreter in (nightly) Rust"]]></title><description><![CDATA[
<p>I'm not sure how this would be useful in Rust, but macros and tail calls are what allows one to (for example) write iterative loops in Scheme, which doesn't have a native loop syntax.<p>Maybe the same idea can be used in Rust where some constructs are easier to write in recursive form instead of a loop?<p>In any case, here's a silly example of a `for-loop` macro in Scheme using a tail call:<p><pre><code>    (define-syntax for-loop
      (syntax-rules ()
        ((for-loop var start end body ...)
         (letrec ((loop (lambda (var)
                          (unless (>= var end)
                            body ...
                            (loop (+ var 1))))))  ; <-- tail call
           (loop start)))))
</code></pre>
And here's how you'd use it to print the numbers 0 to 9:<p><pre><code>    (for-loop i 0 10
              (display i)
              (newline))
</code></pre>
This macro expands to a function that calls itself to loop. Since Scheme is guaranteed to have proper tail calls, the calls are guaranteed to not blow the stack.<p>(Note that you'll probably never see a `letrec` used like this: people would use a named `let`, which is syntax sugar for that exact usage of `letrec`. I wrote it the `letrec` way to make the function explicit).</p>
]]></description><pubDate>Mon, 06 Apr 2026 03:00:09 +0000</pubDate><link>https://news.ycombinator.com/item?id=47656484</link><dc:creator>moefh</dc:creator><comments>https://news.ycombinator.com/item?id=47656484</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47656484</guid></item><item><title><![CDATA[New comment by moefh in "What came after the 486?"]]></title><description><![CDATA[
<p>Shouldn't that be 0xc8c70ff0, since we're talking about a little-endian CPU? (according to this[1] the bytes in memory are F0 0F C7 C8).<p>On the other hand, I probably wouldn't have recognized the F00F bug mention if you had actually written 0xc8c70ff0.<p>[1] <a href="https://en.wikipedia.org/wiki/Pentium_F00F_bug" rel="nofollow">https://en.wikipedia.org/wiki/Pentium_F00F_bug</a></p>
]]></description><pubDate>Thu, 26 Mar 2026 18:15:24 +0000</pubDate><link>https://news.ycombinator.com/item?id=47533865</link><dc:creator>moefh</dc:creator><comments>https://news.ycombinator.com/item?id=47533865</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47533865</guid></item><item><title><![CDATA[New comment by moefh in "New evidence that Cantor plagiarized Dedekind?"]]></title><description><![CDATA[
<p>Being "not very inaccurate" is very different from publishing outright fabricated quotes, which is what Ars Technica did and later admitted to: <a href="https://arstechnica.com/staff/2026/02/editors-note-retraction-of-article-containing-fabricated-quotations/" rel="nofollow">https://arstechnica.com/staff/2026/02/editors-note-retractio...</a></p>
]]></description><pubDate>Sat, 28 Feb 2026 22:40:22 +0000</pubDate><link>https://news.ycombinator.com/item?id=47201118</link><dc:creator>moefh</dc:creator><comments>https://news.ycombinator.com/item?id=47201118</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47201118</guid></item><item><title><![CDATA[New comment by moefh in "Raspberry Pi Pico 2 at 873.5MHz with 3.05V Core Abuse"]]></title><description><![CDATA[
<p>Great stuff.<p>It wouldn't be surprising if the RP2350 gets officially certified to run at something above the max supported clock at launch (150MHz), though obviously nothing close to 800MHz. That happened to the RP2040[1], which at launch nominally supported 133MHz but now it's up to 200MHz (the SDK still defaults to 125MHz for compatibility, but getting 200MHz is as simple as toggling a config flag[2]).<p>[1] <a href="https://www.tomshardware.com/raspberry-pi/the-raspberry-pi-picos-rp2040-has-been-certified-for-200-mhz-clock-speeds-up-from-133-mhz" rel="nofollow">https://www.tomshardware.com/raspberry-pi/the-raspberry-pi-p...</a><p>[2] <a href="https://github.com/raspberrypi/pico-sdk/releases/tag/2.1.1" rel="nofollow">https://github.com/raspberrypi/pico-sdk/releases/tag/2.1.1</a></p>
]]></description><pubDate>Fri, 20 Feb 2026 13:16:18 +0000</pubDate><link>https://news.ycombinator.com/item?id=47087638</link><dc:creator>moefh</dc:creator><comments>https://news.ycombinator.com/item?id=47087638</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47087638</guid></item><item><title><![CDATA[New comment by moefh in "The most famous transcendental numbers"]]></title><description><![CDATA[
<p>Yes. A number is transcendental if it's not the root of a polynomial with integer coefficients; that's completely independent of how you represent it.</p>
]]></description><pubDate>Wed, 31 Dec 2025 13:37:41 +0000</pubDate><link>https://news.ycombinator.com/item?id=46443949</link><dc:creator>moefh</dc:creator><comments>https://news.ycombinator.com/item?id=46443949</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=46443949</guid></item><item><title><![CDATA[New comment by moefh in "Over 40% of deceased drivers in vehicle crashes test positive for THC: Study"]]></title><description><![CDATA[
<p>We don't know that. We don't even know if there's selection bias.<p>The article says the research was "focusing on 246 deceased drivers who were tested for THC", and that the test usually happens when autopsies are performed. It doesn't say if autopsies are performed for all driver deaths, and it also doesn't say what exactly is "usually".<p>If (for example) autopsy only happens when the driver is suspected of drug use, then there's a clear selection bias.<p>Note that this doesn't mean the study is useless: they were able to see that legalization of cannabis didn't have impact on recreational use.</p>
]]></description><pubDate>Sat, 20 Dec 2025 18:37:49 +0000</pubDate><link>https://news.ycombinator.com/item?id=46338410</link><dc:creator>moefh</dc:creator><comments>https://news.ycombinator.com/item?id=46338410</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=46338410</guid></item><item><title><![CDATA[New comment by moefh in "Checked-size array parameters in C"]]></title><description><![CDATA[
<p>> The fact that the correct type signature, a pointer to fixed-size array, exists and that you can create a struct containing a fixed-size array member and pass that in by value completely invalidates any possible argument for having special semantics for fixed-size array parameters.<p>That's not entirely accurate: "fixed-size" array parameters (unlike pointers to arrays or arrays in structs) actually say that the array must be <i>at least</i> that size, not exactly that size, which makes them way more flexible (e.g. you don't need a buffer of an exact size, it can be larger). The examples from the article are neat but fairly specific because cryptographic functions always work with pre-defined array sizes, unlike most algorithms.<p>Incidentally, that was one of the main complaints about Pascal back in the day (see section 2.1 of [1]): it originally had only fixed-size arrays and strings, with no way for a function to accept a "generic array" or a "generic string" with size unknown at compile time.<p>[1] <a href="https://www.cs.virginia.edu/~evans/cs655/readings/bwk-on-pascal.html" rel="nofollow">https://www.cs.virginia.edu/~evans/cs655/readings/bwk-on-pas...</a></p>
]]></description><pubDate>Thu, 04 Dec 2025 00:18:00 +0000</pubDate><link>https://news.ycombinator.com/item?id=46142178</link><dc:creator>moefh</dc:creator><comments>https://news.ycombinator.com/item?id=46142178</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=46142178</guid></item><item><title><![CDATA[New comment by moefh in "Checked-size array parameters in C"]]></title><description><![CDATA[
<p>It's not intuitive, although arguably conforms to the general C philosophy of not getting in the way unless the code has no chance of being right.<p>For example, both compilers do complain if you try to pass a literal NULL to `f1` (because that can't possibly be right), the same way they warn about division by a literal zero but give no warnings about dividing by a number that is not known to be nonzero.</p>
]]></description><pubDate>Wed, 03 Dec 2025 23:46:50 +0000</pubDate><link>https://news.ycombinator.com/item?id=46141896</link><dc:creator>moefh</dc:creator><comments>https://news.ycombinator.com/item?id=46141896</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=46141896</guid></item><item><title><![CDATA[New comment by moefh in "Checked-size array parameters in C"]]></title><description><![CDATA[
<p>It was always considered bad not (just) because it's ugly, but because it hides potential problems and adds no safety at all: a `[static N]` parameter tells the compiler that the parameter will never be NULL, but the function can still be called with a NULL pointer anyway.<p>That's is the current state of both gcc and clang: they will both happily, without warnings, pass a NULL pointer to a function with a `[static N]` parameter, and then REMOVE ANY NULL CHECK from the function, because the argument can't possibly be NULL according to the function signature, so the check is obviously redundant.<p>See the example in [1]: note that in the assembly of `f1` the NULL check is removed, while it's present in the "unsafe" `f2`, making it actually safer.<p>Also note that gcc will at least tell you that the check in `f1()` is "useless" (yet no warning about `g()` calling it with a pointer that could be NULL), while clang sees nothing wrong at all.<p>[1] <a href="https://godbolt.org/z/ba6rxc8W5" rel="nofollow">https://godbolt.org/z/ba6rxc8W5</a></p>
]]></description><pubDate>Wed, 03 Dec 2025 23:26:10 +0000</pubDate><link>https://news.ycombinator.com/item?id=46141723</link><dc:creator>moefh</dc:creator><comments>https://news.ycombinator.com/item?id=46141723</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=46141723</guid></item><item><title><![CDATA[New comment by moefh in "You can't fool the optimizer"]]></title><description><![CDATA[
<p>> It probably shouldn't do that if you create a dynamic library that needs a symbol table but for an ELF binary it could, no?<p>It can't do that because the program might load a dynamic library that depends on the function (it's perfectly OK for a `.so` to depend on a function from the main executable, for example).<p>That's one of the reasons why a very cheap optimization is to always use `static` for functions when you can. You're telling the compiler that the function doesn't need to be visible outside the current compilation unit, so the compiler is free to even inline it completely and never produce an actual callable function, if appropriate.</p>
]]></description><pubDate>Wed, 03 Dec 2025 13:05:00 +0000</pubDate><link>https://news.ycombinator.com/item?id=46134034</link><dc:creator>moefh</dc:creator><comments>https://news.ycombinator.com/item?id=46134034</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=46134034</guid></item><item><title><![CDATA[New comment by moefh in "New magnetic component discovered in the Faraday effect"]]></title><description><![CDATA[
<p>> Special Relativity (non-accelerating frames of reference, i.e. moving at a constant speed)<p>Sorry, but this is a pet peeve of mine: special relativity works perfectly well in accelerating frames of reference, as long as the spacetime remains flat (a Minkowski space[1]), for example when any curvature caused by gravity is small enough that you can ignore it.<p>[1] <a href="https://en.wikipedia.org/wiki/Minkowski_space" rel="nofollow">https://en.wikipedia.org/wiki/Minkowski_space</a></p>
]]></description><pubDate>Mon, 24 Nov 2025 15:31:34 +0000</pubDate><link>https://news.ycombinator.com/item?id=46035163</link><dc:creator>moefh</dc:creator><comments>https://news.ycombinator.com/item?id=46035163</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=46035163</guid></item><item><title><![CDATA[New comment by moefh in "China has added forest the size of Texas since 1990"]]></title><description><![CDATA[
<p>That's not great context: China and India have huge populations, it's expected that they should be at the top.<p>Better context can be found here[1] (countries by emission per capita). It's still not great because it shows a lot of small countries at the top. For example: Palau is the first, but it has a population of a few thousand people, so their emissions are a rounding error when compared to other countries.<p>[1] <a href="https://en.wikipedia.org/wiki/List_of_countries_by_carbon_dioxide_emissions_per_capita" rel="nofollow">https://en.wikipedia.org/wiki/List_of_countries_by_carbon_di...</a></p>
]]></description><pubDate>Thu, 30 Oct 2025 02:34:56 +0000</pubDate><link>https://news.ycombinator.com/item?id=45755807</link><dc:creator>moefh</dc:creator><comments>https://news.ycombinator.com/item?id=45755807</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=45755807</guid></item><item><title><![CDATA[New comment by moefh in "Date bug in Rust-based coreutils affects Ubuntu 25.10 automatic updates"]]></title><description><![CDATA[
<p>> In C, sloppy programmers will [...]<p>> In Rust, sloppy programmers will [...]<p>You're comparing apples to oranges.<p>Inexperienced people who don't know better will make safe, bloated code in Rust.<p>Experienced people who simply ignore C warnings because they're "confident they know better" (as the other poster said) will write unsafe Rust code regardless of all the care in the world put in choosing sensible defaults or adding a borrow checker to the language. They will use `unsafe` and call it a day -- I've seen it happen more than once.<p>To fix this you have to change the process being used to write software -- you need to make sure people can't simply (for example) ignore C warnings or use Rust's `unsafe` at will.</p>
]]></description><pubDate>Sat, 25 Oct 2025 16:18:16 +0000</pubDate><link>https://news.ycombinator.com/item?id=45704997</link><dc:creator>moefh</dc:creator><comments>https://news.ycombinator.com/item?id=45704997</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=45704997</guid></item><item><title><![CDATA[New comment by moefh in "Date bug in Rust-based coreutils affects Ubuntu 25.10 automatic updates"]]></title><description><![CDATA[
<p>It seems like you're trying to fix a social problem (programmers don't care about doing a good job) with a technical solution (change the programming languages). This simply doesn't work.<p>People who write C code ignoring warnings are the same people who in Rust will resort to writing unsafe with raw pointers as soon as they hit the first borrow check error. If you can't force them to care about C warnings, how are you going to force them to care about Rust safety?<p>I've seen this happen; it's not seen at large because the vast majority of people writing Rust code in public do it because they want to, not because they're forced.</p>
]]></description><pubDate>Sat, 25 Oct 2025 15:32:45 +0000</pubDate><link>https://news.ycombinator.com/item?id=45704654</link><dc:creator>moefh</dc:creator><comments>https://news.ycombinator.com/item?id=45704654</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=45704654</guid></item><item><title><![CDATA[New comment by moefh in "Date bug in Rust-based coreutils affects Ubuntu 25.10 automatic updates"]]></title><description><![CDATA[
<p>> Another respect is that C allows omitting curly braces after an if-statement, which makes bugs like <a href="https://www.codecentric.de/en/knowledge-hub/blog/curly-braces" rel="nofollow">https://www.codecentric.de/en/knowledge-hub/blog/curly-brace...</a> possible.<p>This is a silly thing to point to, and the very article you linked to argues that the lack of curly braces is not the actual problem in that situation.<p>In any case, both gcc and clang will give a warning about code like that[1] with just "-Wall" (gcc since 2016 and clang since 2020). Complaining about this in 2025 smells of cargo cult programming, much like people who still use Yoda conditions[2] in C and C++.<p>C does have problems that make it hard to write safe code with it, but this is not one of them.<p>[1] <a href="https://godbolt.org/z/W74TsoGhr" rel="nofollow">https://godbolt.org/z/W74TsoGhr</a><p>[2] <a href="https://en.wikipedia.org/wiki/Yoda_conditions" rel="nofollow">https://en.wikipedia.org/wiki/Yoda_conditions</a></p>
]]></description><pubDate>Fri, 24 Oct 2025 12:34:23 +0000</pubDate><link>https://news.ycombinator.com/item?id=45693983</link><dc:creator>moefh</dc:creator><comments>https://news.ycombinator.com/item?id=45693983</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=45693983</guid></item><item><title><![CDATA[New comment by moefh in "OpenAI researcher announced GPT-5 math breakthrough that never happened"]]></title><description><![CDATA[
<p>> Kevin Weil had the two previous quotes in his context when he did his post and didn't consider the fact that readers would only see the first level, so wouldn't have Sebastien Bubek's post in mind when they read his.<p>No, Weil said he himself misunderstood Sellke's post[1].<p>Note Weil's wording (10 <i>previously unsolved</i> Erdos problems) vs. Sellke's wording (10 Erdos problems that <i>were listed as open</i>).<p>[1] <a href="https://x.com/kevinweil/status/1979270343941591525" rel="nofollow">https://x.com/kevinweil/status/1979270343941591525</a></p>
]]></description><pubDate>Sun, 19 Oct 2025 14:21:36 +0000</pubDate><link>https://news.ycombinator.com/item?id=45634350</link><dc:creator>moefh</dc:creator><comments>https://news.ycombinator.com/item?id=45634350</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=45634350</guid></item><item><title><![CDATA[New comment by moefh in "How I bypassed Amazon's Kindle web DRM"]]></title><description><![CDATA[
<p>Eh, I wouldn't be so sure. Reading the DMCA, their code does seem to do what the law says you can't do[1]:<p><pre><code>    "No person shall circumvent a technological measure that effectively controls access to a work protected under this title [...]"
</code></pre>
with these definitions[2]:<p><pre><code>    (A) to “circumvent a technological measure” means to descramble a scrambled work, to decrypt an encrypted work, or otherwise to avoid, bypass, remove, deactivate, or impair a technological measure, without the authority of the copyright owner; and

    (B) a technological measure “effectively controls access to a work” if the measure, in the ordinary course of its operation, requires the application of information, or a process or a treatment, with the authority of the copyright owner, to gain access to the work.
</code></pre>
I think (A) pretty clearly applies: the glyphs being randomized in each request obviously counts as being "scrambled", the method used by the author with the hashes clearly descrambles them by matching the provided SVG images to the letters rendered with the book's font.<p>I'm less sure about (B), not being a lawyer, but I think it's so generic that it does apply: the "ordinary course of [...] operation" of reading the book requires running the apps provided by Amazon. This seems to fit "requires the application of [...] a process [...] with the authority of the copyright owner".<p>[1] <a href="https://www.law.cornell.edu/uscode/text/17/1201" rel="nofollow">https://www.law.cornell.edu/uscode/text/17/1201</a><p>[2] <a href="https://www.law.cornell.edu/definitions/uscode.php?width=840&height=800&iframe=true&def_id=17-USC-1838631189-2041315756&term_occur=999&term_src=title:17:chapter:12:section:1201" rel="nofollow">https://www.law.cornell.edu/definitions/uscode.php?width=840...</a></p>
]]></description><pubDate>Fri, 17 Oct 2025 07:41:08 +0000</pubDate><link>https://news.ycombinator.com/item?id=45614195</link><dc:creator>moefh</dc:creator><comments>https://news.ycombinator.com/item?id=45614195</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=45614195</guid></item><item><title><![CDATA[New comment by moefh in "Love C, hate C: Web framework memory problems"]]></title><description><![CDATA[
<p>I don't understand why people think this is safer, it's the complete opposite.<p>With that `char msg[static 1]` you're telling the compiler that `msg` can't possibly be NULL, which means it will optimize away any NULL check you put in the function. But it will still happily call it with a pointer that could be NULL, with no warnings whatsoever.<p>The end result is that with an "unsafe" `char *msg`, you can at least handle the case of `msg` being NULL. With the "safe" `char msg[static 1]` there's nothing you can do -- if you receive NULL, you're screwed, no way of guarding against it.<p>For a demonstration, see[1]. Both gcc and clang are passed `-Wall -Wextra`. Note that the NULL check is removed in the "safe" version (check the assembly). See also the gcc warning about the "useless" NULL check ("'nonnull' argument 'p' compared to NULL"), and worse, the lack of warnings in clang. And finally, note that neither gcc or clang warn about the call to the "safe" function with a pointer that could be NULL.<p>[1] <a href="https://godbolt.org/z/qz6cYPY73" rel="nofollow">https://godbolt.org/z/qz6cYPY73</a></p>
]]></description><pubDate>Fri, 10 Oct 2025 09:44:12 +0000</pubDate><link>https://news.ycombinator.com/item?id=45536974</link><dc:creator>moefh</dc:creator><comments>https://news.ycombinator.com/item?id=45536974</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=45536974</guid></item></channel></rss>