HNHacker News
TopNewBestAskShowJobs

uzerfcwn

59 karma · joined June 16, 2023

submissionscomments
uzerfcwn··on The Hugging Face incident and the road ahead
It's even crazier that a year ago the prevailing discourse would've been, "You can't do that or you'll face criminal charges." and now it's crickets.
uzerfcwn··on Mario Meets Pareto
The data came from wow.tools (which has since been replaced by https://wago.tools) and Wowhead. I still have some code but it has so many ad-hoc scripts and sections that I commented in/out while experimenting that I'd feel embarrassed sharing it.
uzerfcwn··on Mario Meets Pareto
I did similar analysis a couple years ago for optimizing item builds in WoW classic. The tricky part in WoW is that there are 15ish item slots with hundreds of item choices for each slot, so the total number of builds is well over 100^15.

I ended up using a divide-and-conquer style approach, where I 1) pruned items that weren't on the Pareto frontier individually for each slot, 2) took the two slots X and Y that had the least items after pruning and grouped them by calculating Z:={x+y|x∈X,y∈Y}, 3) pruned items that weren't on the Pareto frontier in Z, and 4) repeated steps 2-3 until there was only one group remaining, comprised of the full Pareto-optimal item builds.

This ran in a couple of seconds, as opposed to the other solutions I tried that took somewhere between minutes and years. The downside was that including set bonuses into the model took extra work.

uzerfcwn··on Turtle WoW classic server announces shutdown after Blizzard wins injunction
> my understanding is a "clean room" reverse engineering for interoperability was fair use and not a copyright violation

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.

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 might 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.

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. https://github.com/cmangos/mangos-tbc and https://github.com/cmangos/tbc-db.

uzerfcwn··on An incoherent Rust
I don't know what quotemstr was specifically talking about, but here's my own take.

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).

Consider the following Rust functions:

    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()?;}
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.

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 can't 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.

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.

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.

[1] https://koka-lang.github.io

uzerfcwn··on Mathematicians disagree on the essential structure of the complex numbers (2024)
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]

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.

[1] https://hsm.stackexchange.com/questions/170/how-did-group-th...

uzerfcwn··on Notepad++ supply chain attack breakdown
> When I run 'notepad dir1/file1.txt', the package should not sneakily be able to access dir2.

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?

uzerfcwn··on Mozilla appoints new CEO Anthony Enzor-Demeo
Thanks for sharing this! Went and changed some keybinds right away.
uzerfcwn··on I think nobody wants AI in Firefox, Mozilla
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.

On the flip side, changing keybinds in Firefox requires forking, but the defaults aren't too bad.

uzerfcwn··on Environment variables are a legacy mess: Let's dive deep into them
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.
uzerfcwn··on Cap'n Web: a new RPC system for browsers and web servers
> Is there anything C# _doesn’t_ have?

Pi types, existential types and built-in macros to name a few.

uzerfcwn··on ChatControl update: blocking minority held but Denmark is moving forward anyway
Last month, a Finnish court judged that using derogatory words in an email sent privately to the offended person 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.

[1] https://www.iltalehti.fi/kotimaa/a/6c9a65fe-f706-449e-b0d9-1...

[2] https://old.reddit.com/r/Suomi/comments/1mv9usq

uzerfcwn··on Unexpected productivity boost of Rust
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.

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.

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.

[0] https://en.wikipedia.org/wiki/Hindley%E2%80%93Milner_type_sy...

uzerfcwn··on Show HN: I've been building an ERP for manufacturing for the last 3 years
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.
uzerfcwn··on Most RESTful APIs aren't really RESTful
> Most web apps today use APIs that return JSON and are called by JavaScript. Can you use REST for such services

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.

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.

> does REST require a switch to HTML representation ... How such HTML representation can even use PUT and DELETE verbs

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.

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.

uzerfcwn··on YouTube's new anti-adblock measures
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.
uzerfcwn··on Programming languages should have a tree traversal primitive
C++ also has generators[1], but the author is perhaps unaware of them.

[1] https://en.cppreference.com/w/cpp/coroutine/generator

uzerfcwn··on Pipelining might be my favorite programming language feature
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:

    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;
    }
uzerfcwn··on An epic treatise on error models for systems programming languages
That looks more like ad hoc union types than sum types. What happens if you do:

    data FooResult = Number | Number
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|.

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:

    ErrorA = FileNotFoundError | ParsingError
    ErrorB = FileNotFoundError | PermissionError
    ErrorC = ErrorA | ErrorB // Oops, trying to ad hoc sum FileNotFoundError twice
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.

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].

[1] https://github.com/dotnet/csharplang/blob/main/proposals/Typ...

uzerfcwn··on DOGE puts $1 spending limit on government employee credit cards
Reminds me of this sketch https://youtu.be/iB1hQkqtNso
uzerfcwn··on Escape the walled garden and algorithm black boxes with RSS feeds
For me, that advanced reader is Thunderbird. It has amazing customizability with userchrome.css, web extensions, about:config and developer tools from Firefox.
uzerfcwn··on C++ is an absolute blast
Once, I wanted to write a C# function roughly like this:

  (T1, ..., Tn) Apply<T1, ..., Tn>((Func<P, T1>, ..., Func<P, Tn>) args)
This is not possible in C# because the language doesn't have variadic generics. Instead, I used runtime reflection and wrote something like this:

  object[] Apply(Func<P, object>[] args)
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.
uzerfcwn··on Lies we tell ourselves to keep using Golang (2022)
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.

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.

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.

uzerfcwn··on JSON Patch
You can add to the end of an array by using the path /.../myarray/-, i.e., the index is replaced by a dash.

JSON patch is indeed not idempotent.

uzerfcwn··on Let's talk about animation quality
The dataset Github page https://github.com/simonalexanderson/MotoricaDanceDataset does mention some missing finger data:

> Session 2: Casual dancing ... No finger motion.

> Session 3: Vintage jazz dancing ... Fingers captured with Manus gloves, which unfortunately suffered in quality due to sensor drift during rapid motion.

> Session 4: Street dancing ... Simplified finger motion (markers on thumb, index finger, and pinky according to the OptiTrack layout).

The first video in the article does have a bit of finger motion, so I'm guessing it's from session 4. Toes also look a bit iffy and clip into the ground instead of curling at times.

uzerfcwn··on Practices of Reliable Software Design
It seems like the author had some very specific read and write pattern in mind when they designed for performance, but it's never explicitly stated. The problem setting only stated that "reads are more common than writes", but that's not really saying much when discussing performance. For example, a HTML server commonly has a small set of items that are most frequently read, and successive reads are not very strongly dependent. On the other hand, a PIM system may often get iterative reads correlated on some fuzzy search filter, which will be slow and thrash cache pretty badly if the system is optimized for different access patterns.

When designing software, you first need to nail down the requirements, which I didn't really find in TFA.

uzerfcwn··on Flaw has Microsoft Authenticator overwriting MFA accounts, locking users out
> Then there are other webapps which seem to implement their own login flow: they figure your session is expired, but don't allow you to switch accounts. The only way to use a different account from this flow is to sign out of the current one, which, of course, signs you out from everywhere.

Container tabs[1] are great for these. My work browser has a separate container for each of my frequently used Azure logins. When I need to use one of those pesky apps, I just open it in the respective container.

[1] https://addons.mozilla.org/en-US/firefox/addon/multi-account...

uzerfcwn··on `find` + `mkdir` is Turing complete
The definition of tag systems says "add P(x) to the end" but doesn't define x.

I can't spot errors in the logic or code, though I'm not an expert either.

uzerfcwn··on Getting the World Record in Hatetris (2022)
I find it interesting how the author's first approach was to use a black box neural network instead of the evidently simpler beam search. As far as I'm aware, beam search was widely considered to be the simple method for game optimization just a decade ago.

Sure, new methods will always replace old methods, just like CNNs replaced SIFT for image processing. However, I feel that beam search is one of those elementary methods that you'd always want to check first, similar to A* and quicksort. Even though there are fancy neural networks for game optimization, pathfinding and sorting, it's easier to get started with elementary methods because they're simple and tractable.

uzerfcwn··on A proposal to add signals to JavaScript
As an end user, I love when web applications pass events through the DOM tree, because it allows me to easily create plugins by hooking on the same events. Youtube is a prime example of how to do things right.

Unfortunately, modern frameworks really want to use their own event channels, which makes hooking a pain.

Page 1 of 2Next →