<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: rbehrends</title><link>https://news.ycombinator.com/user?id=rbehrends</link><description>Hacker News RSS</description><docs>https://hnrss.org/</docs><generator>hnrss v2.1.1</generator><lastBuildDate>Thu, 14 May 2026 14:37:33 +0000</lastBuildDate><atom:link href="https://hnrss.org/user?id=rbehrends" rel="self" type="application/rss+xml"></atom:link><item><title><![CDATA[New comment by rbehrends in "Heritability of human life span is ~50% when heritability is redefined"]]></title><description><![CDATA[
<p>> That matches what I assumed it meant, and it seems like OP and the post are arguing that that is some kind of surprising interpretation.<p>The unintuitive part is that in quantitative genetics, heritability is defined in terms of <i>variance</i> in traits at the population level, not as the passing of traits from parents to offspring (that would be heredity [1]). Of course, I may have misinterpreted what you said in your OP when you cited the wiktionary definition of "[g]enetically transmissible from parent to offspring", and if so, I apologize, but at the time it seemed to me that you were talking about heredity.<p>> Uhm, no. That is exactly what I (and I think most people) would expect the answer to be.<p>What the article is talking about is that if you fix Var(E) = 0, then Var(P) = Var(G) in the standard heritability model, i.e. all phenotypic variance is explained entirely by genotypic variance (because in that model, Var(P) = Var(G) + Var(E)).<p>Fun fact (even if only tangentially unrelated): In Western countries, wearing glasses is a highly heritable trait, because wearing glasses is a strong proxy variable for refractive error [2], such as nearsightedness, which is highly heritable. It is often brought up as another example of how the quantitative genetics definition does not match conventional use of the word.<p>[1] <a href="https://en.wikipedia.org/wiki/Heredity" rel="nofollow">https://en.wikipedia.org/wiki/Heredity</a><p>[2] <a href="https://en.wikipedia.org/wiki/Refractive_error" rel="nofollow">https://en.wikipedia.org/wiki/Refractive_error</a></p>
]]></description><pubDate>Wed, 13 May 2026 20:35:55 +0000</pubDate><link>https://news.ycombinator.com/item?id=48127170</link><dc:creator>rbehrends</dc:creator><comments>https://news.ycombinator.com/item?id=48127170</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=48127170</guid></item><item><title><![CDATA[New comment by rbehrends in "Heritability of human life span is ~50% when heritability is redefined"]]></title><description><![CDATA[
<p>Heritability has a <i>very</i> specific meaning in quantitative genetics [1], which in many ways is not what your intuition would suggest [2]. It is this usage that the article talks about that.<p>That said, there are plenty of critiques of this definition of heritability, and not just because it is different from what a layperson would expect it to mean.<p>For example, the way it is used also usually has a big problem in that the standard formula assumes that Cov(G, E) = 0 (or at least is negligible), whereas in practice that is not actually true [3, 4].<p>This definition of heritability is also mathematically flawed in that it assumes (without evidence) that P = G + E, or at least can be reasonably approximated this way. Given that human development is the result of a feedback loop involving genetic and environmental factors, one would expect a model closer to something like a Markov chain. Proposed justifications of a simple additive model as an approximation (e.g. via the central limit theorem for highly polygenic traits) have to my knowledge never been tested.<p>More recent genome-wide association studies [5] have actually shown a considerable gap between heritability estimates from genotype data and heritability estimates from twin studies, known as the "missing heritability problem".<p>[1] <a href="https://en.wikipedia.org/wiki/Heritability" rel="nofollow">https://en.wikipedia.org/wiki/Heritability</a><p>[2] <a href="https://en.wikipedia.org/wiki/Genetic_variance" rel="nofollow">https://en.wikipedia.org/wiki/Genetic_variance</a><p>[3] <a href="https://en.wikipedia.org/wiki/Gene%E2%80%93environment_interaction" rel="nofollow">https://en.wikipedia.org/wiki/Gene%E2%80%93environment_inter...</a><p>[4] <a href="https://en.wikipedia.org/wiki/Gene%E2%80%93environment_correlation" rel="nofollow">https://en.wikipedia.org/wiki/Gene%E2%80%93environment_corre...</a><p>[5] <a href="https://en.wikipedia.org/wiki/Genome-wide_association_study" rel="nofollow">https://en.wikipedia.org/wiki/Genome-wide_association_study</a></p>
]]></description><pubDate>Wed, 13 May 2026 18:56:22 +0000</pubDate><link>https://news.ycombinator.com/item?id=48125942</link><dc:creator>rbehrends</dc:creator><comments>https://news.ycombinator.com/item?id=48125942</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=48125942</guid></item><item><title><![CDATA[New comment by rbehrends in "OpenCode – Open source AI coding agent"]]></title><description><![CDATA[
<p>No, the problem is that when logging in, the provider's website can provide an authentication shell command that OpenCode will send to the shell sight unseen, even if it is "rm -rf /home". This "feature" is completely unnecessary for the agent to function as an agent, or even for authentication. It's not about it being the default, it's about it being there at all and being designed that way.</p>
]]></description><pubDate>Sat, 21 Mar 2026 18:57:32 +0000</pubDate><link>https://news.ycombinator.com/item?id=47470100</link><dc:creator>rbehrends</dc:creator><comments>https://news.ycombinator.com/item?id=47470100</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47470100</guid></item><item><title><![CDATA[New comment by rbehrends in "OpenCode – Open source AI coding agent"]]></title><description><![CDATA[
<p>I am more concerned about their, umm, gallant approach to security. Not only that OpenCode is permissive by default in what it is allowed to do, but that it apparently tries to pull its config from the web (provider-based URL) by default [1]. There is also this open GitHub issue [2], which I find quite concerning (worst case, it's an RCE vulnerability).<p>[1] <a href="https://opencode.ai/docs/config/#precedence-order" rel="nofollow">https://opencode.ai/docs/config/#precedence-order</a><p>[2] <a href="https://github.com/anomalyco/opencode/issues/10939" rel="nofollow">https://github.com/anomalyco/opencode/issues/10939</a></p>
]]></description><pubDate>Fri, 20 Mar 2026 23:55:53 +0000</pubDate><link>https://news.ycombinator.com/item?id=47462469</link><dc:creator>rbehrends</dc:creator><comments>https://news.ycombinator.com/item?id=47462469</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47462469</guid></item><item><title><![CDATA[New comment by rbehrends in "EU Council Approves New "Chat Control" Mandate Pushing Mass Surveillance"]]></title><description><![CDATA[
<p>There is the Parliament's legislative train website [1]. However, it only tracks actual legislative steps, not the intra-Council negotiations, so the proposal's page appears to be have been largely inactive since 2024 [2].<p>[1] <a href="https://www.europarl.europa.eu/legislative-train/" rel="nofollow">https://www.europarl.europa.eu/legislative-train/</a><p>[2] <a href="https://www.europarl.europa.eu/legislative-train/theme-a-new-era-for-european-defence-and-security/file-combating-child-sexual-abuse-online" rel="nofollow">https://www.europarl.europa.eu/legislative-train/theme-a-new...</a></p>
]]></description><pubDate>Fri, 28 Nov 2025 14:33:40 +0000</pubDate><link>https://news.ycombinator.com/item?id=46078995</link><dc:creator>rbehrends</dc:creator><comments>https://news.ycombinator.com/item?id=46078995</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=46078995</guid></item><item><title><![CDATA[New comment by rbehrends in "Git: Introduce Rust and announce it will become mandatory in the build system"]]></title><description><![CDATA[
<p>> The shell, perl and python are likely for scripting and not used during runtime.<p>Some git subcommands are implemented in these. git filter-branch is a shell script, git cvsimport is a Perl script, and git p4 (perforce interop) is a Python script. There are not too many left these days (git add -p/-i also used to call a Perl script), but they exist.</p>
]]></description><pubDate>Sat, 20 Sep 2025 15:48:12 +0000</pubDate><link>https://news.ycombinator.com/item?id=45314362</link><dc:creator>rbehrends</dc:creator><comments>https://news.ycombinator.com/item?id=45314362</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=45314362</guid></item><item><title><![CDATA[New comment by rbehrends in "Germany is not supporting ChatControl – blocking minority secured"]]></title><description><![CDATA[
<p>> Of course the member states drafted and agreed to those and that's why pressure should be on governments to stop hand over the keys to Brussels.<p>What specific example are you thinking of where additional power was handed to Brussels through an amendment of the treaties?<p>> That's in addition to the constant Commission push for more power...<p>If you are worried about the executive trying to expand its power (and something that should be kept in check), may I suggest that the US is not actually a great example right now for how to avoid that?</p>
]]></description><pubDate>Thu, 11 Sep 2025 12:01:59 +0000</pubDate><link>https://news.ycombinator.com/item?id=45210555</link><dc:creator>rbehrends</dc:creator><comments>https://news.ycombinator.com/item?id=45210555</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=45210555</guid></item><item><title><![CDATA[New comment by rbehrends in "Germany is not supporting ChatControl – blocking minority secured"]]></title><description><![CDATA[
<p>> The EU does not so as time passes the EU's power keeps creeping up.<p>Actually, the EU has the same concept of enumerated powers (called "competences" in the case of the EU). They are listed in articles 2-6 TFEU [1]. You may argue over whether the EU has too many competences or (in some areas) too little, but it's the same principle. The EU cannot legislate outside areas where power has been expressly conferred to it by the treaties.<p>This is in fact one point of contention over the "chat control" legislation. It is supposed to be enacted under the "internal market" competence, but similar to the US commerce clause, there is a legal debate over whether that competence is actually sufficient to enable such legislation or whether it is legal cover for encroachment on competences reserved to the member states.<p>This would of course be up to the ECJ to decide, just as the US Suprement Court would have to decide if any given US federal legislation is covered by the commerce clause.<p>In addition, there is the Charter of Fundamental Rights, and the ECJ could also strike down EU legislation (as it has done before) if it violates the rights protected by the Charter.<p>[1] <a href="https://en.wikisource.org/wiki/Consolidated_version_of_the_Treaty_on_the_Functioning_of_the_European_Union/Part_One:_Principles#TITLE_I:_CATEGORIES_AND_AREAS_OF_UNION_COMPETENCE" rel="nofollow">https://en.wikisource.org/wiki/Consolidated_version_of_the_T...</a></p>
]]></description><pubDate>Thu, 11 Sep 2025 11:28:09 +0000</pubDate><link>https://news.ycombinator.com/item?id=45210286</link><dc:creator>rbehrends</dc:creator><comments>https://news.ycombinator.com/item?id=45210286</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=45210286</guid></item><item><title><![CDATA[New comment by rbehrends in "Germany is not supporting ChatControl – blocking minority secured"]]></title><description><![CDATA[
<p>What you are proposing would amount replacing the current bicameral legislature (with the European Parliament as the lower house and the Council of the EU as the upper house) with a unicameral legislature. That would actually make it easier for bad laws to be passed, especially as the supermajority required in the Council is currently the biggest obstacle for this kind of legislation.<p>I'll also note that nothing here is per se undemocratic. Both the Parliament and the Council are made up of elected members. The members of the Council (as members of the national governments) are indirectly elected, but elected all the same. Direct election is not a requirement for a democracy (see election of the US president or the US Senate prior to the 17th amendment or the Senate of Canada right now).<p>That does not mean that there isn't plenty of valid criticism of the EU's current structure, but claiming that it is not "actually democratic" falls far short of a meaningful critique.</p>
]]></description><pubDate>Thu, 11 Sep 2025 11:07:34 +0000</pubDate><link>https://news.ycombinator.com/item?id=45210150</link><dc:creator>rbehrends</dc:creator><comments>https://news.ycombinator.com/item?id=45210150</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=45210150</guid></item><item><title><![CDATA[New comment by rbehrends in "Kotlin-Lsp: Kotlin Language Server and Plugin for Visual Studio Code"]]></title><description><![CDATA[
<p>Aside from the often cited nullability issue, here is an (incomplete) list of important things that Kotlin still does better than Java:<p>- First class, fully functional closures.
- Non-abstract classes and methods are final by default.
- Named parameters.
- Easy to write iterators via sequence { ... }
- First class support for unsigned types.</p>
]]></description><pubDate>Thu, 22 May 2025 16:48:44 +0000</pubDate><link>https://news.ycombinator.com/item?id=44063897</link><dc:creator>rbehrends</dc:creator><comments>https://news.ycombinator.com/item?id=44063897</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=44063897</guid></item><item><title><![CDATA[New comment by rbehrends in "Conservative GC can be faster than precise GC"]]></title><description><![CDATA[
<p>The same argument would apply to any non-compacting allocator, because the worst case memory blowup due to external fragmentation is huge. But such cases are extremely rarely observed in practice, so people use e.g. standard malloc()/free() implementations or non-compacting garbage collectors without being concerned about that.<p>In addition, there are plenty of cases where memory usage is unbounded or excessive, not because of allocator behavior, but because of programming mistakes. In fact, memory can sometimes blow up just because of large user inputs and very few systems are prepared for properly handling OOM conditions that happen legitimately.<p>Case in point: Both CRuby and Apple's JavaScriptCore have garbage collectors that use conservative stack scanning and are widely used in production systems without the world ending.<p>That said, you're probably not going to use conservative stack scanning because of collection speed alone. There are other trade-offs between conservative stack scanning and precise stack scanning that weigh more heavily.<p>I'll add the caveat that I would be very cautious about using a conservative GC on 32-bit systems, but on 64-bit systems this is about as much of a concern as memory fragmentation.</p>
]]></description><pubDate>Sat, 07 Sep 2024 16:21:46 +0000</pubDate><link>https://news.ycombinator.com/item?id=41474720</link><dc:creator>rbehrends</dc:creator><comments>https://news.ycombinator.com/item?id=41474720</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=41474720</guid></item><item><title><![CDATA[New comment by rbehrends in "Kotlin for data analysis"]]></title><description><![CDATA[
<p>What happens under the hood is that a `sequence {}` call creates an instance of `SequenceScope`, which has `yield()` and `yieldAll()` methods. When executing the block, `this` will reference that particular instance and `yield()` is essentially `this.yield()` and will call the method on the scope instance.<p>The actual functionality is then provided by the coroutine system, though a lot of the heavy lifting is done by the optimizer to eliminate all or most of the runtime overhead.</p>
]]></description><pubDate>Thu, 29 Aug 2024 08:51:18 +0000</pubDate><link>https://news.ycombinator.com/item?id=41388711</link><dc:creator>rbehrends</dc:creator><comments>https://news.ycombinator.com/item?id=41388711</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=41388711</guid></item><item><title><![CDATA[New comment by rbehrends in "Kotlin for data analysis"]]></title><description><![CDATA[
<p>As somebody who uses and likes both Kotlin and Python (and quite a few other languages), I'd be cautious with using a subjective term such as "more expressive", too, but I can possibly shed some light on where such feelings come from.<p>Personally, I see Kotlin as the closest thing to a statically typed Smalltalk that we have among major languages, and that's a major draw.<p>A key part here is that Kotlin closures are fully-featured equivalents of Smalltalk blocks (up to and including even non-local returns [1]), whereas in many other languages that falls short. Java does not allow mutation of local variables and Python restricts lambdas to normal expressions.<p>I find code whose behavior can be parameterized by code to be an essential feature of modern-day programming and this should be as frictionless as possible.<p>This is also a situation where syntax matters, and while it isn't quite as nice as Smalltalk, Kotlin's syntax (esp. with trailing closures) make such code as readable as possible in a brace-style language with minimal additional syntactic noise.<p>In a similar vein, the functionality of Smalltalk's cascades is offered through scope functions [2], especially `.run {}`.<p>But ultimately, fully-featured closures (and the fact that they are widely used in the standard library) power a lot of the things that people seem to like about Kotlin.<p>That does not mean that there aren't downsides. The limitations of running on the JVM are one (e.g. while Kotlin has workarounds for the JVM's type erasure, they're still workarounds), and then Gradle is arguably Kotlin's weakest point (which apparently even JetBrains are seeing, given their investment in Amper).<p>That said, personally I'd say Kotlin's static typing and performance would be the primary reasons for me to reach for Kotlin over Python, not necessarily expressiveness. Type annotations in Python + mypy etc. just aren't the same experience, and writing performance-sensitive code in Python can be very tricky/hacky when you can't delegate the hot paths to numpy or other existing C/C++/Rust libraries.<p>Conversely, Python often has a leg up when it comes to fast prototyping and scripting, even with Kotlin Worksheets in IntelliJ IDEA and with kscript.<p>[1] Which, to be clear, are a nice-to-have thing, not essential, but still impressive that even that was covered, when previously Ruby was the only major language I know of that did it.<p>[2] <a href="https://kotlinlang.org/docs/scope-functions.html" rel="nofollow">https://kotlinlang.org/docs/scope-functions.html</a></p>
]]></description><pubDate>Thu, 29 Aug 2024 08:40:48 +0000</pubDate><link>https://news.ycombinator.com/item?id=41388656</link><dc:creator>rbehrends</dc:creator><comments>https://news.ycombinator.com/item?id=41388656</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=41388656</guid></item><item><title><![CDATA[New comment by rbehrends in "Kotlin for data analysis"]]></title><description><![CDATA[
<p>Like this?<p><pre><code>  sequence { for (x in 0..<10) for (y in 0..<10) yield(x*y) }.toList()
</code></pre>
Now, technically, Kotlin doesn't have <i>list</i> comprehensions, only the equivalent of generator expressions in Python, so you have to tack an extra `.toList()` on at the end if you want a list, but you can write pretty much any for comprehension in Python in a similar way in Kotlin.<p>On the other hand, you're not limited to for loops/ifs inside such a generator, but can use fairly arbitrary control flow.</p>
]]></description><pubDate>Thu, 29 Aug 2024 03:20:44 +0000</pubDate><link>https://news.ycombinator.com/item?id=41386949</link><dc:creator>rbehrends</dc:creator><comments>https://news.ycombinator.com/item?id=41386949</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=41386949</guid></item><item><title><![CDATA[New comment by rbehrends in "Kotlin for data analysis"]]></title><description><![CDATA[
<p>> the 'yield' keyword<p>Am I missing something here?<p><pre><code>  $ cat fib.kts
  fun fib() = sequence {
    var a = 1; var b = 1
    while (true) {
      yield(a)
      a = b.also { b += a }
    }
  }

  println(fib().take(10).joinToString(" -> "))
  println(fib().first { it >= 50 })
  $ kotlin fib.kts
  1 -> 1 -> 2 -> 3 -> 5 -> 8 -> 13 -> 21 -> 34 -> 55
  55
</code></pre>
Of course, yield() is a function in Kotlin, not a keyword, but the same functionality is there.</p>
]]></description><pubDate>Thu, 29 Aug 2024 03:16:41 +0000</pubDate><link>https://news.ycombinator.com/item?id=41386922</link><dc:creator>rbehrends</dc:creator><comments>https://news.ycombinator.com/item?id=41386922</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=41386922</guid></item><item><title><![CDATA[New comment by rbehrends in "Borrow Checking, RC, GC, and the Eleven () Other Memory Safety Approaches"]]></title><description><![CDATA[
<p>> Note: I wasn't criticizing the paper. I was criticizing the comment, which claimed "it’s better" to view these as special cases.<p>I didn't assume you were. My note about it being a good paper was just a general "this is worth reading" recommendation.<p>> "Can handle" is quite the hedge. You "can" walk across the continent too, but at what cost?<p>It's not a hedge. You claimed that (tracing) GC can handle cycles, while RC was "the opposite", which I read to mean that you believe it cannot.<p>While we are at it, let's go through the basics of trial deletion.<p>Trial deletion first looks at possible candidates for objects involved in a cycle (in the original algorithm, those were objects whose RC got decremented without reaching zero). Then, you do a recursive decrement of their children's (and their children's children's, and so forth) reference counts.<p>Unlike with regular reference counting decrements, you visit children even if the reference count doesn't reach zero. The net result is that reference counts are reduced only along internal paths, but that objects that are still reachable from external paths have reference counts > 0 after that.<p>Thus, any object with a reference count of zero after this step must be part of an internal cycle and can be deleted. All other objects have their original reference counts restored.<p>Because trial deletion operates on reference counts differently, it's not something that you can easily implement as a library, which is why you don't see it much except when a language implementation chooses to go with reference counting over a tracing GC.<p>> You're saying Python uses RC to handle reference cycles, and doesn't need a GC for that? If so please ask them to update the documentation, because right now it specifically says "you can disable the collector if you are sure your program does not create reference cycles". <a href="https://docs.python.org/3/library/gc.html" rel="nofollow">https://docs.python.org/3/library/gc.html</a><p>This is a terminology thing. Python uses a variant (generational) trial deletion approach [1]. It's not a traditional tracing GC, and it's also not inaccurate, because GC can mean more than using a traditional tracing GC.<p>> Nobody said "real time". I just said "hard guarantee".<p>I was not sure what you meant, so I answered both, as you may have noticed.<p>[1] <a href="https://github.com/python/cpython/blob/796b3fb28057948ea5b98f7eb0c0f3af6a1e276e/Python/gc.c#L1126">https://github.com/python/cpython/blob/796b3fb28057948ea5b98...</a></p>
]]></description><pubDate>Thu, 25 Apr 2024 08:34:45 +0000</pubDate><link>https://news.ycombinator.com/item?id=40154964</link><dc:creator>rbehrends</dc:creator><comments>https://news.ycombinator.com/item?id=40154964</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=40154964</guid></item><item><title><![CDATA[New comment by rbehrends in "Borrow Checking, RC, GC, and the Eleven () Other Memory Safety Approaches"]]></title><description><![CDATA[
<p>First of all, I recommend giving the paper a read, because I think you're misunderstanding the claim (plus, it is a very good paper). The claim is not that they are equivalent, but that tracing GC and reference counting are dual solutions to the same problem, two ends of the same spectrum if you will, with hybrid solutions existing in between.<p>Second, what you seem to consider to be fundamental characteristics of tracing GC and RC is not in fact so fundamental.<p>For starters, RC absolutely can handle cycles (e.g. through trial deletion). Such implementations may be difficult or impossible to implement as pure library solutions, but there is nothing that says it can't be done. The most prominent example of a programming language that uses such an approach is probably Python.<p>Nor does the claim that tracing GC cannot provide hard performance guarantees in the general case (while RC does) hold up under closer examination. Leaving aside the problem that it's already non-trivial to provide <i>hard real time</i> performance guarantees for malloc()/free() and ignoring the issue of cascading deletions, it doesn't hold under the more relaxed assumptions discussed downthread.<p>For starters, we have such predictability only for the single-threaded case, not for arbitrary multi-threaded situations. And even in the single-threaded case, there are real use cases where predicting performance becomes functionally intractable. Examples are implementations of binary decision diagrams or certain persistent data structures, where the presence of shared subgraphs of arbitrary size make predicting performance of individual deallocations impractical.<p>In contrast, in the single-threaded case we can absolutely bound individual operations of a tracing GC by either a constant or (in the case of arbitrarily sized allocations) make them linear in the number of bytes allocated (e.g. Baker's treadmill).<p>What is true is that in the absence of cycles, (naive) reference counting will free memory at the earliest opportunity, which is not something we can say for tracing GC.</p>
]]></description><pubDate>Thu, 25 Apr 2024 06:21:08 +0000</pubDate><link>https://news.ycombinator.com/item?id=40154099</link><dc:creator>rbehrends</dc:creator><comments>https://news.ycombinator.com/item?id=40154099</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=40154099</guid></item><item><title><![CDATA[New comment by rbehrends in "Garbage collection for systems programmers (2023)"]]></title><description><![CDATA[
<p>You can express immutability simply by making all instance variables private and not providing any methods to modify them.</p>
]]></description><pubDate>Thu, 04 Apr 2024 12:07:54 +0000</pubDate><link>https://news.ycombinator.com/item?id=39929333</link><dc:creator>rbehrends</dc:creator><comments>https://news.ycombinator.com/item?id=39929333</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=39929333</guid></item><item><title><![CDATA[New comment by rbehrends in "Garbage collection for systems programmers (2023)"]]></title><description><![CDATA[
<p>Delaying deletions can result in significant memory overhead [1].<p>TANSTAAFL, as they say.<p>[1] <a href="https://citeseerx.ist.psu.edu/document?repid=rep1&type=pdf&doi=3eef7ac270d541eae847a12a7762672c4f2638cd" rel="nofollow">https://citeseerx.ist.psu.edu/document?repid=rep1&type=pdf&d...</a></p>
]]></description><pubDate>Wed, 03 Apr 2024 06:24:51 +0000</pubDate><link>https://news.ycombinator.com/item?id=39914236</link><dc:creator>rbehrends</dc:creator><comments>https://news.ycombinator.com/item?id=39914236</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=39914236</guid></item><item><title><![CDATA[New comment by rbehrends in "Garbage collection for systems programmers (2023)"]]></title><description><![CDATA[
<p>> It may not be a problem in a language like Rust, where the compiler understands the concept of immutability. But most (if not all) mainstream languages except Rust don’t. Your object may be immutable in January but in February someone makes a change in a class used 10 layers below and suddenly your class is no longer immutable. Add invisible sharing to that and your code explodes.<p>No offense, but this strikes me as a strawman argument. What software design methodology leads to immutable types suddenly being made mutable? Outside of dynamic languages, where is support for immutability not there?<p>Note that any language with proper information hiding can expressly do immutability (literally going back to the days of Modula-2), plus of course several mainstream languages that have first-class language features to represent immutability for added convenience.<p>Finally, this is only one example. One underlying problem is that if all reference counts need to be capped at one, you have to either switch to full reference counting or to copy the underlying data.<p>You can see this play out in the std::collections::HashSet interface. Operations like intersection, union, difference, and symmetric difference return iterators rather than sets. While there are also operators that do return sets, such as bitor, that's implemented as follows.<p><pre><code>    fn bitor(self, rhs: &HashSet<T, S>) -> HashSet<T, S> {
        self.union(rhs).cloned().collect()
    }
    </code></pre>
Because the result and the argument can't in general share references to elements, you end up essentially doing a deep copy for e.g. a set of strings, which you want to minimize as much as possible. Thus, limitations on the sharing of references dictate aspects of the API.<p>> Abstractions understood as „I can change only X without changing Y” (aka GoF OOP patterns or most Clean Code OOP patterns) are overrated anyways. Readability and understandability of code is more important than ability to add something without changing something else. If code is readable and constraints are enforced by the compiler, it is easy and safe to change.<p>So, you never work with third-party libraries where you do not control the API and have never written libraries to be consumed by other teams/third parties?</p>
]]></description><pubDate>Wed, 03 Apr 2024 06:23:44 +0000</pubDate><link>https://news.ycombinator.com/item?id=39914224</link><dc:creator>rbehrends</dc:creator><comments>https://news.ycombinator.com/item?id=39914224</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=39914224</guid></item></channel></rss>