<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: uzerfcwn</title><link>https://news.ycombinator.com/user?id=uzerfcwn</link><description>Hacker News RSS</description><docs>https://hnrss.org/</docs><generator>hnrss v2.1.1</generator><lastBuildDate>Mon, 04 May 2026 09:50:29 +0000</lastBuildDate><atom:link href="https://hnrss.org/user?id=uzerfcwn" rel="self" type="application/rss+xml"></atom:link><item><title><![CDATA[New comment by uzerfcwn in "Turtle WoW classic server announces shutdown after Blizzard wins injunction"]]></title><description><![CDATA[
<p>> my understanding is a "clean room" reverse engineering for interoperability was fair use and not a copyright violation<p>To my understanding, reverse engineering algorithms and interfaces is not a copyright violation since those cannot be copyrighted (i.e. fair use is not relevant). However, a WoW server also distributes e.g. quest texts, which most certainly are copyrightable, since the collective of all quests is comparable to a fantasy novel.<p>In backend terms (which isn't really relevant in court but helps illustrate the division), every WoW server is said to have a "core" that contains the gameplay logic (netcode, movement, hit rolls, object interactions, etc.) and a "world database" (item names and stats, NPC names and stats, quests, etc.). The core <i>might</i> be considered a collection of clean room reverse engineered algorithms, which aren't copyrightable. However, the world database is full of copyrighted material, and a server distributing that data to clients will violate Blizzard's copyrights. You could avoid this by deleting all of Blizzard's stuff from the world database and writing your own content, but it's not relevant here since Turtle WoW didn't do that.<p>Nonetheless, vbezhenar's point stands because there are open source server implementations that host both the core and the database on Github, see e.g. <a href="https://github.com/cmangos/mangos-tbc" rel="nofollow">https://github.com/cmangos/mangos-tbc</a> and <a href="https://github.com/cmangos/tbc-db" rel="nofollow">https://github.com/cmangos/tbc-db</a>.</p>
]]></description><pubDate>Thu, 23 Apr 2026 04:11:36 +0000</pubDate><link>https://news.ycombinator.com/item?id=47872182</link><dc:creator>uzerfcwn</dc:creator><comments>https://news.ycombinator.com/item?id=47872182</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47872182</guid></item><item><title><![CDATA[New comment by uzerfcwn in "An incoherent Rust"]]></title><description><![CDATA[
<p>I don't know what quotemstr was specifically talking about, but here's my own take.<p>The ideal error handling is inferred algebraic effects like in Koka[1]. This allows you to add a call to an error-throwing function 15 layers down the stack and it's automatically propagated into the type signatures of all functions up the stack (and you can see the inferred effects with a language server or other tooling, similar to Rust's inferred types).<p>Consider the following Rust functions:<p><pre><code>    fn f1() -> Result<(), E1> {...}
    fn f2() -> Result<(), E2> {...}
    fn f3() -> Result<(), E3> {...}
    fn f4() -> Result<(), E4> {f1()?; f2()?;}
    fn f5() -> Result<(), E5> {f1()?; f3()?;}
    fn f6() -> Result<(), E6> {f4()?; f5()?;}
</code></pre>
Now, how do you define E4, E5 and E6? The "correct" way is to use sum types, i.e., `enum E4 {E1(E1), E2(E2)}`, `enum E5 {E1(E1), E3(E3)}` and `enum E6 {E1(E1), E2(E2), E3(E3)}` with the appropriate From traits. The problem is that this involves a ton of boilerplate even with thiserror handling some stuff like the From traits.<p>Since this is such a massive pain, Rust programs tend to instead either define a single error enum type that has all possible errors in the crate, or just use opaque errors like the anyhow crate. The downside is that these approaches lose type information: you no longer know that a function <i>can't</i> return some specific error (unless it returns no errors at all, which is rare), which is ultimately not so different from those languages where you have to guard against bizarre runtime errors.<p>Worse yet, if f1 has to be changed such that it returns 2 new errors, then you need to go through all error types in the call stack and flatten the new errors manually into E4, E5 and E6. If you don't flatten errors, then you end up rebuilding the call stack in error types, which is a whole different can of worms.<p>Algebraic effects just handle all of this more conveniently. That said, an effect system like Koka's isn't viable in a systems programming language like Rust, because optimizing user-defined effects is difficult. But you could have a special compiler-blessed effect for exceptions; algebraic checked exceptions, so to speak. Rust already does this with async.<p>[1] <a href="https://koka-lang.github.io" rel="nofollow">https://koka-lang.github.io</a></p>
]]></description><pubDate>Fri, 27 Mar 2026 10:16:44 +0000</pubDate><link>https://news.ycombinator.com/item?id=47540866</link><dc:creator>uzerfcwn</dc:creator><comments>https://news.ycombinator.com/item?id=47540866</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47540866</guid></item><item><title><![CDATA[New comment by uzerfcwn in "Mathematicians disagree on the essential structure of the complex numbers (2024)"]]></title><description><![CDATA[
<p>Group theory entering quantum physics is a particularly funny example, because some established physicists at the time really hated the purely academic nature of group theory that made it difficult to learn.[1]<p>If you include practical applications inside computers and not just the physical reality, then Galois theory is the most often cited example. Galois himself was long dead when people figured out that his mathematical framework was useful for cryptography.<p>[1] <a href="https://hsm.stackexchange.com/questions/170/how-did-group-theory-enter-quantum-mechanics" rel="nofollow">https://hsm.stackexchange.com/questions/170/how-did-group-th...</a></p>
]]></description><pubDate>Wed, 11 Feb 2026 18:08:11 +0000</pubDate><link>https://news.ycombinator.com/item?id=46978515</link><dc:creator>uzerfcwn</dc:creator><comments>https://news.ycombinator.com/item?id=46978515</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=46978515</guid></item><item><title><![CDATA[New comment by uzerfcwn in "Notepad++ supply chain attack breakdown"]]></title><description><![CDATA[
<p>> When I run 'notepad dir1/file1.txt', the package should not sneakily be able to access dir2.<p>What happens if the user presses ^O, expecting a file open dialog that could navigate to other directories? Would the dialog be somehow integrated to the OS and run with higher permissions, and then notepad is given permissions to the other directory that the user selects?</p>
]]></description><pubDate>Wed, 04 Feb 2026 04:58:02 +0000</pubDate><link>https://news.ycombinator.com/item?id=46881638</link><dc:creator>uzerfcwn</dc:creator><comments>https://news.ycombinator.com/item?id=46881638</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=46881638</guid></item><item><title><![CDATA[New comment by uzerfcwn in "Mozilla appoints new CEO Anthony Enzor-Demeo"]]></title><description><![CDATA[
<p>Thanks for sharing this! Went and changed some keybinds right away.</p>
]]></description><pubDate>Tue, 16 Dec 2025 20:00:54 +0000</pubDate><link>https://news.ycombinator.com/item?id=46293621</link><dc:creator>uzerfcwn</dc:creator><comments>https://news.ycombinator.com/item?id=46293621</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=46293621</guid></item><item><title><![CDATA[New comment by uzerfcwn in "I think nobody wants AI in Firefox, Mozilla"]]></title><description><![CDATA[
<p>My favourite feature is userChrome. The default chrome sucks in both Chrome and Firefox, but at least Firefox allows me to customize it to my liking without forking the entire browser.<p>On the flip side, changing keybinds in Firefox requires forking, but the defaults aren't too bad.</p>
]]></description><pubDate>Sat, 15 Nov 2025 02:49:11 +0000</pubDate><link>https://news.ycombinator.com/item?id=45934640</link><dc:creator>uzerfcwn</dc:creator><comments>https://news.ycombinator.com/item?id=45934640</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=45934640</guid></item><item><title><![CDATA[New comment by uzerfcwn in "Environment variables are a legacy mess: Let's dive deep into them"]]></title><description><![CDATA[
<p>I feel that Windows Registry is similar legacy cruft as environment variables. Worse yet, most software doesn't document which registry keys it's using, so you have to find them on some ancient forum comment or do the detective work by yourself.</p>
]]></description><pubDate>Tue, 14 Oct 2025 13:03:17 +0000</pubDate><link>https://news.ycombinator.com/item?id=45579546</link><dc:creator>uzerfcwn</dc:creator><comments>https://news.ycombinator.com/item?id=45579546</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=45579546</guid></item><item><title><![CDATA[New comment by uzerfcwn in "Cap'n Web: a new RPC system for browsers and web servers"]]></title><description><![CDATA[
<p>> Is there anything C# _doesn’t_ have?<p>Pi types, existential types and built-in macros to name a few.</p>
]]></description><pubDate>Tue, 23 Sep 2025 04:11:34 +0000</pubDate><link>https://news.ycombinator.com/item?id=45342768</link><dc:creator>uzerfcwn</dc:creator><comments>https://news.ycombinator.com/item?id=45342768</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=45342768</guid></item><item><title><![CDATA[New comment by uzerfcwn in "ChatControl update: blocking minority held but Denmark is moving forward anyway"]]></title><description><![CDATA[
<p>Last month, a Finnish court judged that using derogatory words in an email <i>sent privately to the offended person</i> counts as defamation.[1] When this was discussed in the Finnish Reddit [2], some found it unjust that it counts as defamation even though the message wasn't sent to third parties, but it is indeed how the law was written.<p>[1] <a href="https://www.iltalehti.fi/kotimaa/a/6c9a65fe-f706-449e-b0d9-180122c9e44b" rel="nofollow">https://www.iltalehti.fi/kotimaa/a/6c9a65fe-f706-449e-b0d9-1...</a><p>[2] <a href="https://old.reddit.com/r/Suomi/comments/1mv9usq" rel="nofollow">https://old.reddit.com/r/Suomi/comments/1mv9usq</a></p>
]]></description><pubDate>Mon, 15 Sep 2025 00:31:23 +0000</pubDate><link>https://news.ycombinator.com/item?id=45244787</link><dc:creator>uzerfcwn</dc:creator><comments>https://news.ycombinator.com/item?id=45244787</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=45244787</guid></item><item><title><![CDATA[New comment by uzerfcwn in "Unexpected productivity boost of Rust"]]></title><description><![CDATA[
<p>The core difference between sums and unions is that sum types have cardinality |A+B| = |A| + |B|, whereas union types have cardinality |A∪B| = |A| + |B| - |A∩B|. As you noted, type systems with union types, such as Typescript, also support sum types because you can create disjoint wrapper types (like Ok and Err) and their union type will be semantically equivalent to a sum type, since the intersection is an empty set. In this sense, union types are strictly more powerful than sum types.<p>The downside is that union types require some notion of subtyping, since otherwise A∩B is always empty for distinct A and B. Unfortunately, subtyping is apparently very difficult to implement in HM-like type systems (like Rust and ML) such that it plays well with type inference.[0] Hence, the downside of having union types in a language is that users have to write out types more often.<p>Unlike kibwen, I don't think Rust's type system is particularly essential for new languages. It's a design choice where one side has more powerful types but the other side has more powerful type inference.<p>[0] <a href="https://en.wikipedia.org/wiki/Hindley%E2%80%93Milner_type_system#Subtyping" rel="nofollow">https://en.wikipedia.org/wiki/Hindley%E2%80%93Milner_type_sy...</a></p>
]]></description><pubDate>Sun, 31 Aug 2025 14:53:37 +0000</pubDate><link>https://news.ycombinator.com/item?id=45083611</link><dc:creator>uzerfcwn</dc:creator><comments>https://news.ycombinator.com/item?id=45083611</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=45083611</guid></item><item><title><![CDATA[New comment by uzerfcwn in "Show HN: I've been building an ERP for manufacturing for the last 3 years"]]></title><description><![CDATA[
<p>The problem with forking is that updating becomes a nightmare. Most ERPs provide a stable-ish API and heavily recommend customers to stick with it, because then automatic updates just work.</p>
]]></description><pubDate>Tue, 05 Aug 2025 08:46:44 +0000</pubDate><link>https://news.ycombinator.com/item?id=44795734</link><dc:creator>uzerfcwn</dc:creator><comments>https://news.ycombinator.com/item?id=44795734</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=44795734</guid></item><item><title><![CDATA[New comment by uzerfcwn in "Most RESTful APIs aren't really RESTful"]]></title><description><![CDATA[
<p>> Most web apps today use APIs that return JSON and are called by JavaScript. Can you use REST for such services<p>You kind of could, but it's a bad idea. A core tenet of the REST architecture is that it supports a network of independent servers that provide different services (i.e. webpages) and users can connect to any of them with a generic client (i.e. a web browser). If your mission is to build a specialized API for a specialized client app (a JS web app in your example), then using REST just adds complexity for no reason.<p>For example, you could define a new content-type application/restaurantmenu+json and build a JS client that renders the content-type like a restaurant's homepage. Then you could use your restaurant browser JS client to view any restaurant's menu in a pretty UI... except your own restaurant's server is the only one that delivers application/restaurantmenu+json, so your client is only usable on your own page and you did a whole lot of additional work for no reason.<p>> does REST require a switch to HTML representation ...  How such HTML representation can even use PUT and DELETE verbs<p>Fielding's REST is really just an abstract idea about how to build networks of services. It doesn't require using HTTP(S) or HTML, but it so happens that the most significant example of REST (the WWW) is built on HTTPS and HTML.<p>As in the previous example, you could build a REST app that uses HTTP and application/restaurantmenu+json instead of HTML. This representation could direct the client to use PUT and DELETE verbs if you like, even though these aren't a thing in HTML.</p>
]]></description><pubDate>Wed, 09 Jul 2025 21:01:12 +0000</pubDate><link>https://news.ycombinator.com/item?id=44514701</link><dc:creator>uzerfcwn</dc:creator><comments>https://news.ycombinator.com/item?id=44514701</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=44514701</guid></item><item><title><![CDATA[New comment by uzerfcwn in "YouTube's new anti-adblock measures"]]></title><description><![CDATA[
<p>Feel free to write a bug report to Chrome developers or ManifestV3 authors. In the meantime, Firefox users can override any delivered content with the webRequest API.</p>
]]></description><pubDate>Sat, 21 Jun 2025 09:39:21 +0000</pubDate><link>https://news.ycombinator.com/item?id=44336093</link><dc:creator>uzerfcwn</dc:creator><comments>https://news.ycombinator.com/item?id=44336093</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=44336093</guid></item><item><title><![CDATA[New comment by uzerfcwn in "Programming languages should have a tree traversal primitive"]]></title><description><![CDATA[
<p>C++ also has generators[1], but the author is perhaps unaware of them.<p>[1] <a href="https://en.cppreference.com/w/cpp/coroutine/generator" rel="nofollow">https://en.cppreference.com/w/cpp/coroutine/generator</a></p>
]]></description><pubDate>Wed, 30 Apr 2025 09:30:17 +0000</pubDate><link>https://news.ycombinator.com/item?id=43842919</link><dc:creator>uzerfcwn</dc:creator><comments>https://news.ycombinator.com/item?id=43842919</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=43842919</guid></item><item><title><![CDATA[New comment by uzerfcwn in "Pipelining might be my favorite programming language feature"]]></title><description><![CDATA[
<p>To me, the cool (and uncommon in other languages' standard libraries) part about C++ ranges is that they reify pipelines so that you can cut and paste them into variables, like so:<p><pre><code>    auto get_ids(std::span<const Widget> data)
    {
        auto pipeline = filter(&Widget::alive) | transform(&Widget::id);
        auto sink = to<std::vector>();
        return data | pipeline | sink;
    }</code></pre></p>
]]></description><pubDate>Tue, 22 Apr 2025 04:31:05 +0000</pubDate><link>https://news.ycombinator.com/item?id=43759085</link><dc:creator>uzerfcwn</dc:creator><comments>https://news.ycombinator.com/item?id=43759085</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=43759085</guid></item><item><title><![CDATA[New comment by uzerfcwn in "An epic treatise on error models for systems programming languages"]]></title><description><![CDATA[
<p>That looks more like ad hoc union types than sum types. What happens if you do:<p><pre><code>    data FooResult = Number | Number
</code></pre>
If you can't distinguish the two cases, then it means they're not an actual sum type, since e.g. the set size is |FooResult| = |Number| whereas a sum type should have 2*|Number|.<p>The reason ad hoc union types are avoided in Hindley-Milner (HM) languages is that their usability depends on subtyping, which is incompatible with HM. You could get around this by saying that ad hoc sum types require the types to be distinct, but this would greatly impede usability. For example:<p><pre><code>    ErrorA = FileNotFoundError | ParsingError
    ErrorB = FileNotFoundError | PermissionError
    ErrorC = ErrorA | ErrorB // Oops, trying to ad hoc sum FileNotFoundError twice
</code></pre>
The tried and true solution in HM is to use generic types like Result<A,B>, where you separate the cases with labels Ok and Err.<p>On the other hand, languages with subtyping aren't that averse to ad hoc union types. TS and Python already have them and C# is adding them soonish [1].<p>[1] <a href="https://github.com/dotnet/csharplang/blob/main/proposals/TypeUnions.md#ad-hoc---ad-hoc-unions">https://github.com/dotnet/csharplang/blob/main/proposals/Typ...</a></p>
]]></description><pubDate>Sun, 09 Mar 2025 12:48:01 +0000</pubDate><link>https://news.ycombinator.com/item?id=43308654</link><dc:creator>uzerfcwn</dc:creator><comments>https://news.ycombinator.com/item?id=43308654</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=43308654</guid></item><item><title><![CDATA[New comment by uzerfcwn in "DOGE puts $1 spending limit on government employee credit cards"]]></title><description><![CDATA[
<p>Reminds me of this sketch <a href="https://youtu.be/iB1hQkqtNso" rel="nofollow">https://youtu.be/iB1hQkqtNso</a></p>
]]></description><pubDate>Fri, 21 Feb 2025 17:16:50 +0000</pubDate><link>https://news.ycombinator.com/item?id=43130163</link><dc:creator>uzerfcwn</dc:creator><comments>https://news.ycombinator.com/item?id=43130163</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=43130163</guid></item><item><title><![CDATA[New comment by uzerfcwn in "Escape the walled garden and algorithm black boxes with RSS feeds"]]></title><description><![CDATA[
<p>For me, that advanced reader is Thunderbird. It has amazing customizability with userchrome.css, web extensions, about:config and developer tools from Firefox.</p>
]]></description><pubDate>Mon, 20 Jan 2025 14:01:43 +0000</pubDate><link>https://news.ycombinator.com/item?id=42768808</link><dc:creator>uzerfcwn</dc:creator><comments>https://news.ycombinator.com/item?id=42768808</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=42768808</guid></item><item><title><![CDATA[New comment by uzerfcwn in "C++ is an absolute blast"]]></title><description><![CDATA[
<p>Once, I wanted to write a C# function roughly like this:<p><pre><code>  (T1, ..., Tn) Apply<T1, ..., Tn>((Func<P, T1>, ..., Func<P, Tn>) args)
</code></pre>
This is not possible in C# because the language doesn't have variadic generics. Instead, I used runtime reflection and wrote something like this:<p><pre><code>  object[] Apply(Func<P, object>[] args)
</code></pre>
Although it worked, the downside is that the types T1, ..., Tn are no longer statically known, which means that the function's contract has to be written in comments and the caller has to check them manually. In contrast, C++ has variadic templates, which would allow the compiler to check the types automatically.</p>
]]></description><pubDate>Tue, 24 Dec 2024 18:46:32 +0000</pubDate><link>https://news.ycombinator.com/item?id=42503937</link><dc:creator>uzerfcwn</dc:creator><comments>https://news.ycombinator.com/item?id=42503937</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=42503937</guid></item><item><title><![CDATA[New comment by uzerfcwn in "Lies we tell ourselves to keep using Golang (2022)"]]></title><description><![CDATA[
<p>Exceptions are difficult to discuss because different languages implement exceptions differently, each with their own downsides. That said, I don't think anyone has an issue with bubbling. Even sum type proponents love Rust's ? shorthand, because it makes it easier to propagate Results up the stack.<p>The big issue with exceptions in C#, Python and JS is that they're not included in function signatures, which means you have to look up the list of possible exceptions from documentation or source code. This could be amended with checked exceptions like Java, but it allegedly doesn't mesh well with the type system (I haven't personally written Java to confirm this). And then there's the C++ crowd that slaps noexcept on everything for possible performance gains.<p>Personally, I like the way Koka does exceptions with algebraic effects and type inference. It makes exceptions explicit in function signatures but I don't have to rewrite all the return types (like in Rust) because type inference takes care of all that. It also meshes beautifully with the type system, and the same effect system also generalizes to async, generators, forking and other stuff. Alas, Koka is but a research language, so I still write C# for a living.</p>
]]></description><pubDate>Tue, 26 Nov 2024 23:31:35 +0000</pubDate><link>https://news.ycombinator.com/item?id=42251310</link><dc:creator>uzerfcwn</dc:creator><comments>https://news.ycombinator.com/item?id=42251310</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=42251310</guid></item></channel></rss>