<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: norir</title><link>https://news.ycombinator.com/user?id=norir</link><description>Hacker News RSS</description><docs>https://hnrss.org/</docs><generator>hnrss v2.1.1</generator><lastBuildDate>Wed, 28 Oct 2026 02:49:16 +0000</lastBuildDate><atom:link href="https://hnrss.org/user?id=norir" rel="self" type="application/rss+xml"></atom:link><item><title><![CDATA[New comment by norir in "Small Programs and Languages"]]></title><description><![CDATA[
<p>It is straightforward to pick an isa and then design an ir that closely mirrors it. Codegen from the ir the original isa is dead simple. Other isas are also straightforward except that it may be necessary to introduce virtual registers and implement certain instructions as multiple instructions if there isn't a 1:1 correspondence.<p>I think the op is far too pessimistic about code size and performance. TCC for example produces terrible machine code but I rarely see 3x size or performance diffs compared to clang (at least for the kinds of programs I tend to write). It is also very easy to find edge cases where the clang optimizer makes heinously bad decisions. In one trivial example, I've written a program that has a helper function with no arguments that simply prints "Hello, world!" and a main function that calls the helper 1 million times. With optimizations, the version of clang on my computer inlined the helper call 1 million times, which made the binary I believe 4-6x bigger than -O0. With -O0, I believe compilation took 6 seconds compared to something like 15 minutes with -O2 (tcc took maybe 250ms and produced a binary that I think was about 2x the size of gcc -O0). All that is to say, I have less faith in the quality of optimizing compilers than most.</p>
]]></description><pubDate>Sun, 25 Oct 2026 15:21:56 +0000</pubDate><link>https://news.ycombinator.com/item?id=50232533</link><dc:creator>norir</dc:creator><comments>https://news.ycombinator.com/item?id=50232533</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=50232533</guid></item><item><title><![CDATA[New comment by norir in "Anecdotally, programmers dislike "reduce""]]></title><description><![CDATA[
<p>Anywhere that I could use reduce, I instead write a tail recursive function. This is also why I do not and will not ever choose python or javascript voluntarily.</p>
]]></description><pubDate>Wed, 16 Sep 2026 18:42:26 +0000</pubDate><link>https://news.ycombinator.com/item?id=49731192</link><dc:creator>norir</dc:creator><comments>https://news.ycombinator.com/item?id=49731192</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=49731192</guid></item><item><title><![CDATA[New comment by norir in "Otto Dix, Nietzsche, and the Great War (2019)"]]></title><description><![CDATA[
<p>Comments like this just further my bias against analytic philosophy as a system that helps illuminate the path to human flourishing and truth.</p>
]]></description><pubDate>Tue, 25 Aug 2026 21:27:26 +0000</pubDate><link>https://news.ycombinator.com/item?id=49440893</link><dc:creator>norir</dc:creator><comments>https://news.ycombinator.com/item?id=49440893</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=49440893</guid></item><item><title><![CDATA[New comment by norir in "Zig’s Io.Threaded is neat"]]></title><description><![CDATA[
<p>This reads as rather dismissive and not so humble. Compilers generating suboptimal and sometimes broken code very slowly is the norm, not the exception. Whether or not it's worth worrying about is indeed a development tradeoff but not one that should be so casually dismissed.</p>
]]></description><pubDate>Sat, 22 Aug 2026 14:46:04 +0000</pubDate><link>https://news.ycombinator.com/item?id=49400314</link><dc:creator>norir</dc:creator><comments>https://news.ycombinator.com/item?id=49400314</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=49400314</guid></item><item><title><![CDATA[New comment by norir in "Tail-call optimization in C is relatively recent (2025)"]]></title><description><![CDATA[
<p>It is simple to convert factorial to tail recursive form. In lua, which has tco:<p><pre><code>    local factorial do
      local function impl(n, acc)
        if n == 1 then
          return acc
        else
          return impl(n - 1, acc * n)
        end
      end
      factorial = function(n)
        if n < 0 then
          error("factorial input is negative")
        elseif n <= 1 then
          return 1
        else
          return impl(n - 1, n)
        end
      end
    end
</code></pre>
You could replace impl with an imperative loop:<p><pre><code>    local acc = 1
    repeat
      acc = acc * n
      n = n - 1
    until n == 1
    return acc
</code></pre>
Personally, I find this ugly compared to the tail recursive solution. The loop version only seems more natural if you primarily think in loops. Tail recursion is strictly more powerful than looping since every imperative loop can trivially be converted to a tail recursive function, but the reverse is not true.</p>
]]></description><pubDate>Mon, 10 Aug 2026 19:02:42 +0000</pubDate><link>https://news.ycombinator.com/item?id=49248153</link><dc:creator>norir</dc:creator><comments>https://news.ycombinator.com/item?id=49248153</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=49248153</guid></item><item><title><![CDATA[New comment by norir in "Show HN: Fuse – statically typed functional programming language"]]></title><description><![CDATA[
<p>I would suggest adding objective metrics. How fast is this compiler? How long is the longest fuse program? How long does it take to compile? How fast at runtime is the fuse implementation of several benchmark programs compared to semantically equivalent programs written in other languages?<p>How expressive is fuse? How long are equivalent programs written in fuse/rust/scala/haskell?<p>Can you show me a bug that the fuse compiler catches but some or all of the competition doesn't?</p>
]]></description><pubDate>Sun, 02 Aug 2026 20:16:24 +0000</pubDate><link>https://news.ycombinator.com/item?id=49147885</link><dc:creator>norir</dc:creator><comments>https://news.ycombinator.com/item?id=49147885</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=49147885</guid></item><item><title><![CDATA[New comment by norir in "The Art of 64-bit Assembly"]]></title><description><![CDATA[
<p>If you need better performance than a higher level language affords you, I would not recommend programming directly in asm. Instead, I would write a compiler. Raw asm is seductive since the start up cost is relatively low. You can get started in an afternoon. The trouble is that writing correct assembly is much harder than high level code. You have to hold in your head the register state at all times. You have to know if the function you are calling will clobber registers that you need after the call and manually save/restore them. This will slow down your velocity and the resulting code will be long and difficult to read. It will also rely on a lot of undocumented information that only resided in your head while writing and has since been evicted. Good luck debugging a program written in assembly that no one has looked at for two months.<p>On the other hand, if you write your own non optimizing compiler, you can avoid a lot of these problems by, for example, tracking what registers a function writes and ensuring they are saved before a call and restored after. Then you can actually get the raw performance of handwritten asm without the pitfalls (the resulting code would still he harder to read and maintain than equivalent high level code, but at least it would be tractable). Even better, you can write your own high level assembler that is actually portable to other architectures. For example, instead of directly modeling x86_64, your compiler can model a cpu with 16 general purpose registers and a set of instructions that map to x86_64 instructions. An arm port would be straightforward since arm also has 16 general purpose registers and you can model x86_64 instructions as one or more arm instructions (and you have extra registers for x86_64 instructions that must be modeled as multiple arm instructions). Or you could do the reverse and model 32 general purpose registers using arm instructions and use predefined memory slots as virtual registers on x86_64.</p>
]]></description><pubDate>Sat, 01 Aug 2026 16:30:48 +0000</pubDate><link>https://news.ycombinator.com/item?id=49135827</link><dc:creator>norir</dc:creator><comments>https://news.ycombinator.com/item?id=49135827</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=49135827</guid></item><item><title><![CDATA[New comment by norir in "Thoughts on Integers (2023)"]]></title><description><![CDATA[
<p>I agree with your diagnosis but not entirely the solution. I think fixed sized integers in general are a non portable mistake in a language high level language. Instead, a language should provide arbitrary numeric range types and infer the result type of numeric operations. There should be automatic promotion to bignum when the number no longer fits in the machine word for the target platform. This keeps the focus on the data rather than the register sizes, which is incidental complexity. Where performance is critical, the programmer can annotate function types with specific fixed sized types that fit in registers and the compiler can statically enforce necessary bounds checks on possible overflows. I hypothesize that most software is so inefficient due to architectural flaws that it could be rewritten in a safe language with no undefined and/or unsafe numeric operations and still be at least as fast as the existing software even with the additional overhead of bignums and bounds checking.</p>
]]></description><pubDate>Sun, 26 Jul 2026 22:16:14 +0000</pubDate><link>https://news.ycombinator.com/item?id=49062987</link><dc:creator>norir</dc:creator><comments>https://news.ycombinator.com/item?id=49062987</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=49062987</guid></item><item><title><![CDATA[New comment by norir in "How Our Rust-to-Zig Rewrite Is Going"]]></title><description><![CDATA[
<p>This piece would have been a lot more compelling if they had actually done science on selecting a language for compiler development. From what I can tell, they had an untested hypothesis that a low level systems language is necessary for a high performance compiler <a href="https://www.roc-lang.org/faq#self-hosted-compiler" rel="nofollow">https://www.roc-lang.org/faq#self-hosted-compiler</a> and from that concluded that their only
choice besides rust was zig.<p>I know from experience that this initial assumption is wrong. Compiler performance is dominated by algorithms. The fastes managed languages tend to be at worst within a factor of two for wall time on any given algorithm. Algorithmic differences can be unbounded in their performance gaps. Zig itself is a perfect counterexample to the theory that writing a compiler in a low level systems language will lead to a fast compiler. Roc seems to compile at around 15k lines per second. That is not fast. There were evidently compilers written in ml that did 3k likes per second in 1998 <a href="https://flint.cs.yale.edu/cs421/case-for-ml.html" rel="nofollow">https://flint.cs.yale.edu/cs421/case-for-ml.html</a><p>The zig rewrite of roc looks like the author's second compiler. Compiler and language design is a skill like any other and from my vantage point, they appear to have overcommitted to an initial design at the expense of developing their higher level design skills. In my opinion, the best thing they could do for the future of roc is stop working on their current compiler and use it to write a self hosting compiler for a much smaller subset of roc. They should be able to do that in less than 10k lines of code. They might even find that their self hosting compiler is faster than their zig based bootstrap compiler for the self hosted subset of roc. If the self hosting compiler is inadequate. Now they at least have identified a smaller useful subset of roc and can experiment with different compiler implementations in 10k likes of code rather than 300k lines of code. Then they could actually test the theory of whether or not a low level language is necessary to meet whatever arbitrary compiler performance goals they have.<p>By self hosting, they would also discover what roc features actually matter and they would spend much more time actually writing roc code. The features that are needed to write a self hosted compiler are all features that are generally useful. By improving the self hosted compiler, they also improve downstream programs.</p>
]]></description><pubDate>Thu, 16 Jul 2026 17:09:49 +0000</pubDate><link>https://news.ycombinator.com/item?id=48937260</link><dc:creator>norir</dc:creator><comments>https://news.ycombinator.com/item?id=48937260</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=48937260</guid></item><item><title><![CDATA[New comment by norir in "The LLVM Compiler Infrastructure"]]></title><description><![CDATA[
<p>This infrastructure is also slow and leads to poor compilation times for any language that uses llvm as a backend. In an era of automatic code generation, this will become more and more of a problem as llvm compilation times will become a huge bottleneck. I am very bearish on llvm as a technology and while I will acknowledge its influence, I expect that it is at or near its peak and market share will decline dramatically over the next five to ten years.</p>
]]></description><pubDate>Tue, 07 Jul 2026 02:49:49 +0000</pubDate><link>https://news.ycombinator.com/item?id=48813125</link><dc:creator>norir</dc:creator><comments>https://news.ycombinator.com/item?id=48813125</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=48813125</guid></item><item><title><![CDATA[New comment by norir in "It's not me, it's the compiler"]]></title><description><![CDATA[
<p>This feels like it should have been a warning rather than an optimization in the first place. In my opinion, dead code elimination should only be done during link time optimization where it can be proven that branches are not taken given the whole program information. If there is an unused assignment regardless of the branch, the compiler could emit a warning so the user can do their own dead code elimination, or choose to suppress/ignore the warning. The worst thing a compiler can do is silently incorrectly apply an optimization.<p>Of course, I also feel this way about the vast majority of optimizations. If the compiler can optimize a piece of code, it can also show the user what it thinks the optimal code would be so that they can rewrite it themselves, if they so choose. This both prevents these kinds of miscompiles and prevents compilation times from exploding because the compiler doesn't need to do much work, it primarily just translates the human readable code into machine code.</p>
]]></description><pubDate>Sat, 04 Jul 2026 22:22:51 +0000</pubDate><link>https://news.ycombinator.com/item?id=48789612</link><dc:creator>norir</dc:creator><comments>https://news.ycombinator.com/item?id=48789612</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=48789612</guid></item><item><title><![CDATA[New comment by norir in "Bun has an open PR adding shared-memory threads to JavaScriptCore"]]></title><description><![CDATA[
<p>Perhaps then it would be better to not use tools of this level of complexity.</p>
]]></description><pubDate>Sat, 20 Jun 2026 19:34:43 +0000</pubDate><link>https://news.ycombinator.com/item?id=48612255</link><dc:creator>norir</dc:creator><comments>https://news.ycombinator.com/item?id=48612255</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=48612255</guid></item><item><title><![CDATA[New comment by norir in "CS 6120: Advanced Compilers: The Self-Guided Online Course (2020)"]]></title><description><![CDATA[
<p>I am actively opposed to this design for a first compiler. There is no need for a lexer with a recursive descent parser. Register allocation is also an unnecessary distraction. It is better for a first compiler to compile to a higher level language in which neither register assignment nor memory management are necessary.<p>Optimizing compilers are suboptimal in that they waste enormous amount of time optimizing code that can't or needn't be optimized and even where the optimizations are helpful, they are opaque and at risk of unexpectedly regressing both due to small changes at the source code level or changes in the compiler optimizer, both of which are quite insidious.<p>If instead of optimizing compilers, we had languages that allowed for seamless interop between low level and high level functions, then perhaps an llm becomes the optimizer (or you can invoke the compiler to optimize a specific function by source level rewrite). The benefit of this compared to a traditional optimizing compiler is that the optimization is done once per function and never repeated (until prompted) and the implementation is human readable and not buried in a binary. Moreover, and perhaps even more importantly, by not doing optimizations in the compiler, compilation times can be much faster, easily 100-1000x than state of the art optimizing compiler, while generating equivalent or even better runtime performance. As it has been said: premature optimization is the root of all evil.</p>
]]></description><pubDate>Thu, 18 Jun 2026 19:11:16 +0000</pubDate><link>https://news.ycombinator.com/item?id=48590055</link><dc:creator>norir</dc:creator><comments>https://news.ycombinator.com/item?id=48590055</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=48590055</guid></item><item><title><![CDATA[New comment by norir in "How Terry Tao became an evangelist for AI in math"]]></title><description><![CDATA[
<p>Terry Tao is a next level vibe coder: he inspires people to do his vibe coding for him. As someone with a background in advanced math, though never even close to Tao's level, I find myself skeptical about this type of mathematics. I don't personally find it beautiful and it feels like the line between the profound and the trivial (as in of minimal importance not difficulty) is blurry. One could argue for pure mathematics that is of no practical utility but is aesthetically beautiful, but I struggle to see the beauty in a gargantuan lean proof constructed by 100 different people. Perhaps this work will lead to deeper insight about the universe and the human condition, but I catch a whiff of problem solving for the sake of problem solving untethered from a deeper sense of purpose and meaning.</p>
]]></description><pubDate>Mon, 08 Jun 2026 16:54:42 +0000</pubDate><link>https://news.ycombinator.com/item?id=48447841</link><dc:creator>norir</dc:creator><comments>https://news.ycombinator.com/item?id=48447841</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=48447841</guid></item><item><title><![CDATA[New comment by norir in "Google employees internally share memes about how its AI sucks"]]></title><description><![CDATA[
<p>I think the people with extreme positions are often the most useful because they get closer to the source of the argument. Extreme boosters of ai often want to either bypass developing skills to advance their careers or want to exploit what they perceive to be overpaid labor. Extreme pessimists tend to value skill and autonomy and distrust the people with power above them in the hierarchy. They also may identify with their skills and feel existentially threatened by a society that is rapidly devaluing them.<p>Framing this disagreement as a fundamental misunderstanding of the technical capacity and appropriate use cases, for me, completely misses the plot. Both sides have compelling reasons for their beliefs and the cold rational analysis of the tech is as likely to further entrench the extremes as it is to enlighten.<p>I will also note that in your comment, you lament the dismissal of entire groups of engineers while doing exactly this when you dismiss the loudest voices (as well as those who think highly of their own ability) and imply that it is the loudest voices who are inherently extreme and therefore inferior to the pragmatic engineer who understands tradeoffs and cost benefit analysis.</p>
]]></description><pubDate>Thu, 04 Jun 2026 17:35:42 +0000</pubDate><link>https://news.ycombinator.com/item?id=48401923</link><dc:creator>norir</dc:creator><comments>https://news.ycombinator.com/item?id=48401923</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=48401923</guid></item><item><title><![CDATA[New comment by norir in "American capitalism has taken an apocalyptic turn"]]></title><description><![CDATA[
<p>> We could start off with how are you worse off because of people wealthier than you?<p>You are smart enough to come up with some answers of your own. It's rude to demand others to do your own thinking for you.</p>
]]></description><pubDate>Thu, 04 Jun 2026 05:10:54 +0000</pubDate><link>https://news.ycombinator.com/item?id=48394212</link><dc:creator>norir</dc:creator><comments>https://news.ycombinator.com/item?id=48394212</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=48394212</guid></item><item><title><![CDATA[New comment by norir in "QBE – Compiler Backend – 1.3"]]></title><description><![CDATA[
<p>It is hard for me to fully trust a compiler backend that isn't self hosted. There is a discipline that self hosting imposes that would both improve the quality of their ir as well as the backend itself. A self hosted backend can always be updated to have performance meeting or exceeding the best that llvm or any other backend can offer.</p>
]]></description><pubDate>Tue, 02 Jun 2026 20:42:37 +0000</pubDate><link>https://news.ycombinator.com/item?id=48375990</link><dc:creator>norir</dc:creator><comments>https://news.ycombinator.com/item?id=48375990</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=48375990</guid></item><item><title><![CDATA[New comment by norir in "sp.h: Fixing C by giving it a high quality, ultra portable standard library"]]></title><description><![CDATA[
<p>When using null terminated strings, parsing can be branchless because you don't need bounds checks and can use a jump table indexed by the byte.</p>
]]></description><pubDate>Sun, 24 May 2026 00:47:03 +0000</pubDate><link>https://news.ycombinator.com/item?id=48253157</link><dc:creator>norir</dc:creator><comments>https://news.ycombinator.com/item?id=48253157</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=48253157</guid></item><item><title><![CDATA[New comment by norir in "No way to parse integers in C (2022)"]]></title><description><![CDATA[
<p>This is not a hard thing to do without using a library. The code below is easily adapted to the unsigned case and/or arbitrary base rather than 10.<p><pre><code>    #include <stdio.h>
    int main(int argc, char **argv) {
        if (argc != 2) {
            fprintf(stderr, "usage: require one numeric argument");
        }
        char *nump = argv[1];
        unsigned neg = 0;
        unsigned long long ures = 0;
        if (*nump == '-') {
            neg = 1;
            nump = nump + 1;
        }
        if (!*nump) {
            fprintf(stderr, "require non empty string\n");
            return 1;
        }
        char b;
        while (b = *nump++) {
            if (b >= '0' && b <= '9') {
                unsigned long long nres = (ures * 10) + (b - '0'); 
                if (nres < ures) {
                    fprintf(stderr, "overflow in '%s'\n", argv[1]);
                    return 1;
                }   
                ures = nres;
            } else {
                if (b >= ' ') {
                    fprintf(stderr, "invalid char '%c' in '%s'\n", b, argv[1]); 
                } else {
                    fprintf(stderr, "invalid byte '%d' in '%s'\n", b, argv[1]);
                }
                return 1;  
            }
        }
        long long res = (long long) ures;
        if (neg) {
            if (ures <= 0x8000000000000000ULL) {
                res = -res;
            } else {
                fprintf(stderr, "underflow in '%s'\n", argv[1]);
                return 1;
            }
        } else if (ures > 0x7FFFFFFFFFFFFFFFULL) {
            fprintf(stderr, "overflow in '%s'\n", argv[1]);
            return 1;
        }
        fprintf(stdout, "result: %lld\n", res);
        return 0;
    }</code></pre></p>
]]></description><pubDate>Wed, 20 May 2026 18:38:49 +0000</pubDate><link>https://news.ycombinator.com/item?id=48212113</link><dc:creator>norir</dc:creator><comments>https://news.ycombinator.com/item?id=48212113</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=48212113</guid></item><item><title><![CDATA[New comment by norir in "For thirty years I programmed with Phish on, every day"]]></title><description><![CDATA[
<p>The product and the process are not orthogonal.</p>
]]></description><pubDate>Sun, 03 May 2026 17:59:31 +0000</pubDate><link>https://news.ycombinator.com/item?id=47999599</link><dc:creator>norir</dc:creator><comments>https://news.ycombinator.com/item?id=47999599</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47999599</guid></item></channel></rss>