<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: gsg</title><link>https://news.ycombinator.com/user?id=gsg</link><description>Hacker News RSS</description><docs>https://hnrss.org/</docs><generator>hnrss v2.1.1</generator><lastBuildDate>Thu, 30 Apr 2026 21:37:22 +0000</lastBuildDate><atom:link href="https://hnrss.org/user?id=gsg" rel="self" type="application/rss+xml"></atom:link><item><title><![CDATA[New comment by gsg in "I hate almost all software (2011)"]]></title><description><![CDATA[
<p>This works until the analogue of monotremes shows up to ruin your supposedly flawless categorisation.</p>
]]></description><pubDate>Sun, 15 Aug 2021 06:59:34 +0000</pubDate><link>https://news.ycombinator.com/item?id=28186771</link><dc:creator>gsg</dc:creator><comments>https://news.ycombinator.com/item?id=28186771</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=28186771</guid></item><item><title><![CDATA[New comment by gsg in "The Y Combinator"]]></title><description><![CDATA[
<p>System F doesn't have general recursion.<p>Extensions with a letrec-like construct are common, and are sometimes inaccurately called 'System F', but those languages do not have the properties of System F.</p>
]]></description><pubDate>Wed, 30 Jun 2021 04:23:58 +0000</pubDate><link>https://news.ycombinator.com/item?id=27684839</link><dc:creator>gsg</dc:creator><comments>https://news.ycombinator.com/item?id=27684839</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=27684839</guid></item><item><title><![CDATA[New comment by gsg in "Go: Fuzzing Is Beta Ready"]]></title><description><![CDATA[
<p>There are some examples, for example Crowbar is an OCaml tool that uses AFL to drive property based tests.</p>
]]></description><pubDate>Fri, 04 Jun 2021 13:59:05 +0000</pubDate><link>https://news.ycombinator.com/item?id=27393652</link><dc:creator>gsg</dc:creator><comments>https://news.ycombinator.com/item?id=27393652</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=27393652</guid></item><item><title><![CDATA[New comment by gsg in "Drop millions of allocations by using a linked list (2015)"]]></title><description><![CDATA[
<p>chrisseaton is talking about the bump-pointer allocator in a modern GC, not an implementation of malloc/free. The performance characteristics are quite different.<p>In a generational copying system an object that is bump allocated and then is dead before being copied out of the young generation is indeed cheap - dead objects in the young generation don't need to be freed or even looked at in any way because the space for the young generation can simply be reused after everything is copied out of it. The slow part is elsewhere.</p>
]]></description><pubDate>Fri, 12 Mar 2021 14:38:49 +0000</pubDate><link>https://news.ycombinator.com/item?id=26436262</link><dc:creator>gsg</dc:creator><comments>https://news.ycombinator.com/item?id=26436262</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=26436262</guid></item><item><title><![CDATA[New comment by gsg in "Drop millions of allocations by using a linked list (2015)"]]></title><description><![CDATA[
<p>Yes, this has been done a few times. CDR-coding was a hardware-assisted method of unrolling a Lisp list (complicated somewhat by the need to support mutation of car and cdr) that appeared on Lisp machines, and there's a Appel/Reppy/Shao paper on unrolling linked lists in the context of Standard ML.<p>There's also some interesting work on flattened versions of arbitrary tree structures: <a href="https://engineering.purdue.edu/~milind/docs/ecoop17.pdf" rel="nofollow">https://engineering.purdue.edu/~milind/docs/ecoop17.pdf</a></p>
]]></description><pubDate>Fri, 12 Mar 2021 14:24:18 +0000</pubDate><link>https://news.ycombinator.com/item?id=26436105</link><dc:creator>gsg</dc:creator><comments>https://news.ycombinator.com/item?id=26436105</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=26436105</guid></item><item><title><![CDATA[New comment by gsg in "Drop millions of allocations by using a linked list (2015)"]]></title><description><![CDATA[
<p>You can easily see by searching for 'kmalloc' (or 'malloc') at <a href="https://github.com/torvalds/linux/blob/master/include/linux/list.h" rel="nofollow">https://github.com/torvalds/linux/blob/master/include/linux/...</a> that it does no such thing.<p>Here's the logic for adding a list node:<p><pre><code>    /*
     * Insert a new entry between two known consecutive entries.
     *
     * This is only for internal list manipulation where we know
     * the prev/next entries already!
     */
    static inline void __list_add(struct list_head *new,
                                  struct list_head *prev,
                                  struct list_head *next)
    {
            if (!__list_add_valid(new, prev, next))
                    return;

            next->prev = new;
            new->next = next;
            new->prev = prev;
            WRITE_ONCE(prev->next, new);
    }
</code></pre>
No allocation, just mutating some fields in preexisting list_head structures. Those are by convention stored as a field in whatever struct needs to be kept in the list, which is what 'intrusive' means.</p>
]]></description><pubDate>Fri, 12 Mar 2021 14:06:30 +0000</pubDate><link>https://news.ycombinator.com/item?id=26435927</link><dc:creator>gsg</dc:creator><comments>https://news.ycombinator.com/item?id=26435927</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=26435927</guid></item><item><title><![CDATA[New comment by gsg in "How expensive is integer-overflow trapping in C++?"]]></title><description><![CDATA[
<p>BOUND is pretty slow, and requires an odd start/end pair to be placed in memory. I don't see any reason that it would be better than the usual unsigned comparison + branch that languages with bounds checking tend to use.<p>Besides, much of the difficulty with memory safety in C and C++ is the existence of pointers (or wrappers around them, like iterators), which do not come with an associated length. Length checking machinery can't help with that problem whether special instructions exist or not.<p>In short, it's doubtful that the availability of these old instructions would make any difference to the practicality of bounds checking on modern x86 machines whatsoever.</p>
]]></description><pubDate>Thu, 24 Sep 2020 09:46:11 +0000</pubDate><link>https://news.ycombinator.com/item?id=24576942</link><dc:creator>gsg</dc:creator><comments>https://news.ycombinator.com/item?id=24576942</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=24576942</guid></item><item><title><![CDATA[New comment by gsg in "How expensive is integer-overflow trapping in C++?"]]></title><description><![CDATA[
<p>Sure, but that didn't change much between x86 and x86-64. Perhaps it got a little worse because the SIMD instructions aren't overflow check friendly.</p>
]]></description><pubDate>Thu, 24 Sep 2020 09:20:03 +0000</pubDate><link>https://news.ycombinator.com/item?id=24576806</link><dc:creator>gsg</dc:creator><comments>https://news.ycombinator.com/item?id=24576806</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=24576806</guid></item><item><title><![CDATA[New comment by gsg in "How expensive is integer-overflow trapping in C++?"]]></title><description><![CDATA[
<p>That still exists though? add rax, rbx/jo overflow_error is how you do overflow checking on x86-64.</p>
]]></description><pubDate>Thu, 24 Sep 2020 07:15:21 +0000</pubDate><link>https://news.ycombinator.com/item?id=24576134</link><dc:creator>gsg</dc:creator><comments>https://news.ycombinator.com/item?id=24576134</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=24576134</guid></item><item><title><![CDATA[New comment by gsg in "LLVM merges machine function splitter for reduction in TLB misses"]]></title><description><![CDATA[
<p>> As far as I understand it, this limitation is also the only thing preventing tail-call elimination in C/C++.<p>That is not the case. Guaranteed TCE requires deallocating the stack frame before jumping to the target, but that is not possible when an object is allocated in that frame and its address passed to the target function.<p>In C++ there is also the issue of destructors needing to run after the tail-call returns (in which case it is not really a tail-call).<p>C/C++ compilers can and do eliminate tail calls where possible, but there's no guarantee like you get from a compiler for a functional language.</p>
]]></description><pubDate>Fri, 11 Sep 2020 14:45:16 +0000</pubDate><link>https://news.ycombinator.com/item?id=24443374</link><dc:creator>gsg</dc:creator><comments>https://news.ycombinator.com/item?id=24443374</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=24443374</guid></item><item><title><![CDATA[New comment by gsg in "Defunctionalization and Freyd’s Theorem"]]></title><description><![CDATA[
<p>Interesting if somewhat opaque. I'm familiar with defunctionalisation as an alternative to closure conversion in whole program compilers and as a description of how data types are derived from the lambda calculus - never seen a category theory take on the idea. I don't seem to be able to understand the category theory part though.<p>The suggestion to use a combination of CPS + defunctionalisation to serialise closures is notable, since that pair of transformations gives a fairly close correspondence between a subset of the lambda calculus (plus some primitives) and abstract machine code. Some of the old-school Scheme compilers used CPS as a low-level IR for that reason.</p>
]]></description><pubDate>Wed, 05 Aug 2020 13:02:29 +0000</pubDate><link>https://news.ycombinator.com/item?id=24060321</link><dc:creator>gsg</dc:creator><comments>https://news.ycombinator.com/item?id=24060321</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=24060321</guid></item><item><title><![CDATA[New comment by gsg in "Lambda lifting"]]></title><description><![CDATA[
<p>Lambda lifting is an <i>alternative</i> to closure conversion, so it doesn't get rid of closures so much as obviate introducing them at all.<p>The two transformations are fairly closely related, actually. You can view lambda lifting as closure conversion plus flattening, in the case where the code pointer is unnecessary.</p>
]]></description><pubDate>Sat, 22 Sep 2018 14:34:43 +0000</pubDate><link>https://news.ycombinator.com/item?id=18046110</link><dc:creator>gsg</dc:creator><comments>https://news.ycombinator.com/item?id=18046110</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=18046110</guid></item><item><title><![CDATA[New comment by gsg in "When the Compiler Bites"]]></title><description><![CDATA[
<p>My guess would be that they were thinking h <= SIZE_MAX / w, and added the most obvious logic to avoid a division by zero.</p>
]]></description><pubDate>Wed, 02 May 2018 11:45:13 +0000</pubDate><link>https://news.ycombinator.com/item?id=16975986</link><dc:creator>gsg</dc:creator><comments>https://news.ycombinator.com/item?id=16975986</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=16975986</guid></item><item><title><![CDATA[New comment by gsg in "Implementing and Understanding Type Classes (2014)"]]></title><description><![CDATA[
<p>Monomorphising doesn't work for rank-n polymorphism, either. (This is mentioned on the page.)</p>
]]></description><pubDate>Sun, 29 Apr 2018 05:57:06 +0000</pubDate><link>https://news.ycombinator.com/item?id=16950861</link><dc:creator>gsg</dc:creator><comments>https://news.ycombinator.com/item?id=16950861</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=16950861</guid></item><item><title><![CDATA[New comment by gsg in "Dark side of ergonomics in Rust"]]></title><description><![CDATA[
<p>A bunch of languages have something much like .let/.apply already, since it's pretty much just function application in reverse order:<p><pre><code>    "foo" |> String.length |-> printf "%d\n" |> fun x -> x + 100</code></pre></p>
]]></description><pubDate>Sat, 14 Apr 2018 15:16:06 +0000</pubDate><link>https://news.ycombinator.com/item?id=16837651</link><dc:creator>gsg</dc:creator><comments>https://news.ycombinator.com/item?id=16837651</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=16837651</guid></item><item><title><![CDATA[New comment by gsg in "Compiler Construction: The Art of Niklaus Wirth (2000) [pdf]"]]></title><description><![CDATA[
<p>This is nonsense. Modern compilers don't work by generating the results you see with -O0 and then optimising; the poor quality of -O0 code is the result of skipping register allocation.<p>> Dataflow-directed, "work backwards" techniques might be the solution<p>Destination driven code generation is a known technique. It doesn't generate good enough results to have gotten much attention (better than what you get from -O0, though).</p>
]]></description><pubDate>Sun, 18 Mar 2018 14:29:42 +0000</pubDate><link>https://news.ycombinator.com/item?id=16612066</link><dc:creator>gsg</dc:creator><comments>https://news.ycombinator.com/item?id=16612066</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=16612066</guid></item><item><title><![CDATA[New comment by gsg in "Why writing a linked list in safe Rust is so damned hard"]]></title><description><![CDATA[
<p>First, deriving is just pointer arithmetic and doesn't copy anything. Second, standard flat closure representations already involve copying parts of environments, with any sharing problems addressed by assignment conversion (turning variables that are assigned to into mutable cells, a reference to which can be copied into however many environments is necessary).</p>
]]></description><pubDate>Fri, 23 Feb 2018 05:51:07 +0000</pubDate><link>https://news.ycombinator.com/item?id=16444524</link><dc:creator>gsg</dc:creator><comments>https://news.ycombinator.com/item?id=16444524</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=16444524</guid></item><item><title><![CDATA[New comment by gsg in "Why writing a linked list in safe Rust is so damned hard"]]></title><description><![CDATA[
<p>Mutually recursive functions can be closure converted without cycles by deriving closure values from each other rather than storing them in each other.</p>
]]></description><pubDate>Fri, 23 Feb 2018 03:41:31 +0000</pubDate><link>https://news.ycombinator.com/item?id=16444025</link><dc:creator>gsg</dc:creator><comments>https://news.ycombinator.com/item?id=16444025</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=16444025</guid></item><item><title><![CDATA[New comment by gsg in "Numbers and tagged pointers in early Lisp implementations"]]></title><description><![CDATA[
<p>I see. It seems like that would still make calling supporting routines annoyingly expensive, but perhaps that (and the extra tag memory) doesn't matter as much as I think it does.<p>Good luck with the project.</p>
]]></description><pubDate>Sun, 10 Sep 2017 16:47:55 +0000</pubDate><link>https://news.ycombinator.com/item?id=15212990</link><dc:creator>gsg</dc:creator><comments>https://news.ycombinator.com/item?id=15212990</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=15212990</guid></item><item><title><![CDATA[New comment by gsg in "Numbers and tagged pointers in early Lisp implementations"]]></title><description><![CDATA[
<p>How do you pass arguments? In two registers? On the stack?</p>
]]></description><pubDate>Sun, 10 Sep 2017 15:55:55 +0000</pubDate><link>https://news.ycombinator.com/item?id=15212732</link><dc:creator>gsg</dc:creator><comments>https://news.ycombinator.com/item?id=15212732</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=15212732</guid></item></channel></rss>