HNHacker News
TopNewBestAskShowJobs

wasmperson

230 karma · joined July 4, 2025

submissionscomments
wasmperson··on Ambient CSS v3 – Blender meets CSS
The keyboard controls to select a radio button shouldn't depend on the visual orientation of the radio buttons. Browsers get this right by default, but the radio buttons aren't implemented with `<input type="radio">` and instead are just a row of plain buttons and a bunch of javascript. A quick check in the dev tools confirms the other widgets are similarly implemented :(

I love the look, though!

wasmperson··on Fastpotify
I found a talk with some history of the Spotify client's transition:

https://www.youtube.com/watch?v=9UsnX5X_DF0

It was originally native, then native with some web-based bits, and then the web-based bits slowly ate the whole thing. It seems the ease of development with web-tech compared to C++ (also the better font rendering and screen reader support) was just too tempting.

Interestingly the Spotify client was never based on electron but instead arrived independently at the "chromium + web app" architecture at around the same time as Atom did.

wasmperson··on Fastpotify
This seems like more of a complaint about egui's choice to re-implement all the widgets from scratch than its choice to use an immediate mode API. The two are orthogonal. The IMGUI idea has its roots in a community of people that like implementing things from scratch, but you could implement it on top of native widgets if you wanted to.

The choice to re-implement native widgets from scratch is justifiable if the egui devs think they can do better than the native widgets do. It's also nearly required in practice if they want the toolkit to have consistent behavior across multiple platforms (something people have learned the hard way multiple times across multiple different UI libraries).

It's hard to get it right, but that's why the egui devs are writing a library: so that others can benefit from that hard work. Many of the things you pointed out are just bugs, and bugs can be fixed.

wasmperson··on My Friend Aaron
I think the narrator is the murderer and is lying about the man in the gray tracksuit. The repeated criticism of Aaron's moral character is a sort of rationalization for having killed him, with the underlying motive actually being a combination of greed and envy. Remember that the funds used to kick-start the trading platform came from a hackathon win that Aaron "stole".
wasmperson··on AI companies destroy physical books – let's scan rare books before it's too late
I was also skeptical of this claim but managed to find someone who explains it:

https://downtownbrown.substack.com/p/five-fallacies-ai-and-d...

It's not that individual companies buy all copies of a given book, but that there's more than one book scanning company, and they aren't sharing the scans with each other. The result: books that were rare but nevertheless easy to find for purchase (thanks to the internet) are now vanishing off of the market, becoming de facto no longer accessible to the public.

wasmperson··on Optimizing things in the USSR (2016)
Re-invested how? Many stocks still go up in value even without paying out dividends. Companies with such stocks are technically always re-investing their profits, even as their shareholders become billionaires. It seems to me like a world with the forced re-investment you describe wouldn't be significantly different to the capitalist one.
wasmperson··on Generic Methods in Go 1.27
> Without methods or overloading, you end up in the situation that C and Scheme are in

Well in C at least we now have this:

  #define clear(s) _Generic((s) \
          ,struct list: list_clear \
          ,struct queue: queue_clear \
          ,struct map: map_clear \
  )(s)

  clear(my_map);
  clear(my_list);
  clear(my_queue);
...although it turns out the other nice thing about methods is automatic namespacing.
wasmperson··on Malicious Rust crate Arrayref runs a build-time payload
I don't think this is true. People like to scapegoat the JS standard library but in reality most JS implementations have pretty featureful standard libraries, especially browsers. I've never felt the need to use any third-party libraries in the javascript projects I've worked on (except for maybe `ws`).
wasmperson··on Malicious Rust crate Arrayref runs a build-time payload
There was a recent talk which explored this question (Dependency Cultures, by Richard Feldman):

https://www.youtube.com/watch?v=E82ly38YEEQ

Summary: it's cultural. Rust likely inherited the practice from Nodejs, who inherited it from Ruby. I think in Rust online spaces in particular there is also this undercurrent of "you're not smart enough to use certain parts of the language, so download libraries that handle that stuff for you."

wasmperson··on Digital Immortality
> random websites that LLM crawlers find but humans rarely see

If my experience on random niche web forums is any indication, future AI models will be biased towards the well-being of online casinos.

wasmperson··on Pressed Penny Machine Map
Are these a thing outside the US?

For anyone who's not familiar: all over the place at tourist attractions and airports you can find mechanical presses that will squish a penny with an embossed image. You pick one of 4 images, put in your penny + a couple of quarters and then turn a big crank handle until your newly pressed penny comes out the other side. You'd then collect squished pennies in a little collector's folio/pouch/thing for later viewing.

I guess now that pennies are getting phased out they'll have to "upgrade" the machines to work with other coins...

wasmperson··on The Two Factions of C++ (2024)
> Lack of support for type-safe containers (need to be hack toghether via macros)

Are templates really so much better than macros that the latter deserve to be called a "hack"? The following two examples are both type-safe and have roughly the same semantics and #LoC:

Macros:

  // pair.h
  struct id(pair) { T a, b; };
  static inline struct id(pair) id(make_pair)(T a, T b){
    return (struct id(pair)){ .a = a, .b = b };
  }
  #undef id
  #undef T

  // main.c
  #include <stdio.h>
  #define T int
  #define id(n) n ## _int
  #include "pair.h"
  int main(void){
    struct pair_int p = make_pair_int(12, 13);
    printf("%d %d\n", p.a, p.b);
  }
Templates:

  //pair.h
  template<typename T>
  struct pair { T a, b; };
  template<typename T>
  pair<T> make_pair(T a, T b){
    return (pair<T>){ .a = a, .b = b };
  }

  //main.cpp
  #include <stdio.h>
  #include "pair.h"
  int main(void){
    pair<int> p = make_pair(12, 13);
    printf("%d %d\n", p.a, p.b);
  }
wasmperson··on How Go detects struct copies with sync.noCopy
> (e.g. closing a file), there's generally not much you can do anyway

If closing a file fails then you treat it the same as how you would treat a write failure:

  int err = 1;
  FILE *f = fopen("whatever.txt", "w");
  if(f){
    if(5 == fwrite("Hello", 1, 5, f))
      err = 0;

    if(0 != fclose(f))
      err = 1;
  }
  return err;
Code which writes to files and doesn't check for errors on close is subtly incorrect, although my understanding is that kernel devs bend over backwards to make failure unlikely, probably because everybody does it incorrectly anyway.
wasmperson··on Guiding Ships with Moire Patterns (2018)
> Typically a harbour doesn’t have one razor-thin path of traversable water. Instead there’s a clear pathway that you shouldn’t stray too far away from. The Moire system will give steering advice even if you’re in a safe area, but slightly off the main ‘beam’.

You could fix this issue by just having a second lamp (or two grills in front of the same lamp). If the two arrows point in opposite directions, you're safe. If they point the same direction, you're not.

wasmperson··on Using GCC's Nested Functions with Wide Pointers and No Trampolines II
> lambda expressions can only be passed to template functions

> there is no way to explicitly refer to the compiler-generated name for the lambda type.

"Voldemort" types. While intellectually I get the explanation for why C++/Rust lambdas are like this, I still strongly dislike them. Occasionally being unable to even articulate what something is feels like a failure in language design.

C recently got type inference via the "auto" keyword and it seemed like almost immediately there was a proposal to add voldemort types to the language.

wasmperson··on RISC-V: They Should Have Known Better
> Array accesses take an extra instruction? Either you're in a tight loop walking a tiny array and you don't do the full offset calculation per step, or you're walking over an array in RAM and you're bottlenecked by the memory bus.

I'm not a hardware person, but whenever I look at compiler output I find computed index accesses all over the place in the assembly. This would suggest to me that at least compiler developers believe these addressing modes to be important.

> Yes, that is totally fine. Either you know your target CPU, or you don't - and then you ask your OS for details.

So then my code has to choose between being hardware-dependent or OS-dependent? That doesn't seem ideal.

> "For example, if you are writing a kernel and want it to support all RISC-V cores" - NOBODY IS DOING THAT.

I'd hate to live in a future where linux distros need to ship a separate kernel binary for every random combination of RISC-V features. That said maybe the run-time feature-detection extension will be so widely supported in practice that this wouldn't come up?

wasmperson··on Could a computer scientist build a brain?
> ... effects on past and future astronauts traveling to moon and mars ... wouldn't even survive the journey itself with current technology ...

It's hard to tell given your phrasing but it almost sounds like you're insinuating that traveling to the moon is technically impossible, which would be quite a bold claim given the success of the Apollo missions. Apologies if I misinterpret.

wasmperson··on Using GCC's Nested Functions with Wide Pointers and No Trampolines II
> Lambdas are just anonymous nested functions.

The important feature of lambdas is that they are expressions, not that they lack a name. The advantage of function expressions is you can write the body of the function exactly at the place where it is used. With GCC nested functions you either have to write the body of the function before its first use or else write the declaration of the function twice.

This matters for long chains of continuation passing:

  foo(arg1, arg2, [](){
          // do some work
          bar(arg3, arg4, [](){
                  // do some more work
                  baz(arg5, arg6, [](){
  
                  });
          });
  });
Compare to the following, where the control flow is all out of order:

  void cb(void){
          // Do some work
          void cb2(void){
                  // do some more work
                  void cb3(void){

                  }
                  baz(arg5, arg6, cb3);
          }
          bar(arg3, arg4, cb2);
  }
  foo(arg1, arg2, cb);
wasmperson··on Every Fucking Website (2020)
Adding to the list of random examples: DuckDuckGo's AI answer box shifts the entire page down once the text is done generating, which happens some unpredictable time after the page has finished loading. The size of the downward shift is somehow exactly enough to shift all results down by one, making me accidentally click on the link just above the one I wanted to click.
wasmperson··on ArenaAllocators don't play nicely with ArrayLists
> performance - which is basically the main reason to use an Arena

I'd argue the main reason Zig/C programmers use arenas is for correctness, not performance. You might think of arenas as a performance thing if you consider the alternative to be a GC, but the alternative in Zig/C is usually to do things manually.

wasmperson··on ArenaAllocators don't play nicely with ArrayLists
All of my "arenas" have an additional fixed-length list of function pointers that they call in sequence before resetting/de-allocating the memory. That way they can manage any form of memory (or non-memory resource) you want:

  char *dat = malloc(42);
  arena_push_dtor(ar, dat, free);
  // use dat
Neatly solves the problem of stuff that's too awkward to put in linear memory while still letting you be lazy about cleanup.

Also: if you don't need the contiguity you can simply break up your dynamic array into linked buckets the same way the arena internally does with its own memory. Iteration and random access will still be fast.

wasmperson··on Only 2.6% of the most visited websites have fully valid HTML
I'm curious about how many test with a screen reader even among those who do claim to care about accessibility. Most advice online around accessibility is about using alt attributes and semantic html tags or whatever, not testing your site with accessibility tools.
wasmperson··on To save C, we must save ABI (2022)
> Those are all RPC mechanisms, not an ABI

I'm not sure about the others, but COM is an ABI. There's a bunch of stuff surrounding it that is RPC-like but the core specification is just binary layouts and calling conventions. It's arguably more cross-language than the C ABI since it lets you generate type-safe bindings for any language, unlike in the latter where you need to parse header files.

> You could have an RPC protocol be your only interface to the OS, and that would be a valid design, but would have a performance cost

Maybe it would, but I doubt anybody would notice. The whole "everything is a file" concept on unix is basically just this (also X11/Wayland).

wasmperson··on Windows 11's built-in Weather app wastes more than 1 GB of RAM
> Then C# came and said

It's worse than that. The WASM GC standards team was warned in advance that the proposal wouldn't work for .NET, and they moved forward with it anyway:

https://github.com/WebAssembly/gc/issues/77

They were also warned about Go (though I'm not sure if they ever actually consulted with golang devs):

https://github.com/WebAssembly/gc/issues/36

More links:

https://github.com/dotnet/runtime/issues/94420

https://github.com/golang/go/issues/63904

wasmperson··on Uber SubmitQueue: a high-performance speculative merge queue
> How does this work with a monorepo with hundreds of teams around the globe? If you break the trunk, that means no other teams can release

If you break trunk you just fix it. If a release needs to happen urgently and trunk is broken then you can use stable, which is the last working version of trunk.

EDIT: RE: hundreds of teams: If it's a bunch of independently-built things (libraries, programs, or servers) that happen to share a repo then it will work fine. If you're talking a single mega-project like Linux then maybe not, but Linux is pretty exceptional.

wasmperson··on Uber SubmitQueue: a high-performance speculative merge queue
> I don’t understand how this would work.

It's not all that strange: it's basically how version control worked before everybody switched to git. Anybody still on SVN is basically using this exact development model.

> If you’re using Git and you branch off ‘stable’, you won’t be able to merge to ‘trunk’ unless you rebase to pick up all of its changes.

Yeah, so you just do that. To be clear: most people would be doing their work on trunk. When I say "checkout stable" I mean "checkout stable if you need to start from something that passes CI". In the case where trunk passes CI or was recently passing CI this is basically the same as checking out trunk.

> If a commit were to be reverted in the trunk now you need to revert it from all PRs as well.

Most people push straight into trunk, no PRs needed. For the cases where you need PRs, reverting something in trunk won't affect them: `git revert` adds a new commit just like any other change.

If by "revert" what you actually meant was rolling back trunk to an earlier commit: don't do that.

wasmperson··on The original URL for this prediction will no longer be available in 11 years (2011)
I have no way of knowing whether other people are conscious except by observing their behavior. Similarly, I have no way of knowing whether a machine is conscious except by observing its behavior. If something is outwardly indistinguishable from an intelligent/conscious/sentient/whatever being and you claim that it's still not i/c/s/w, then you've implicitly accepted the possibility that all humans besides you are not i/c/s/w either.

Your tangent on color vision/hearing/pain is not relevant. None of those things are required for i/c/s/w, nor is it obvious that a machine is incapable of feeling those things.

Also you keep using the term "LLM" a bunch here but I wasn't talking about LLMs. The question of machine intelligence is much broader than whatever the current state of the art happens to be.

wasmperson··on CSS: The bomb inside your inbox
There are several reasons someone might prefer to use websites that work without JS:

- The page will load noticeably faster (and likely be faster in a number of other ways).

- The semantics are more predictable (buttons, links, scrolling, text selection, find-in-page, etc. all behave the same as on other websites).

- The page will work in Tor Browser's "maximum security" setting.

- The page is more likely to work better in screen readers or with other less-commonly used web browsing tools.

- The page is more likely to work in older browser versions.

- It used to be that a JS-free page had lighter CPU usage, though newer CSS features and browser setTimeout/setInterval throttling have changed the balance somewhat.

- The page does not require running untrusted/proprietary code on your computer (the browser sandbox is a small comfort).

wasmperson··on The original URL for this prediction will no longer be available in 11 years (2011)
I don't know whether LLMs pass the test as Turing originally worded it, but I always interpreted the success condition to be "is indistinguishable from a human" rather than "can trick someone into thinking it's human". Anthropomorphization is a human weakness, and exploiting that doesn't make something intelligent.

I'd only consider an AI to pass the Turing Test if an expert in how the AI works who prepares in advance for the test is unable to tell it apart from a human. The tester should even be allowed to use automated tools as part of the testing process.

If something is indistinguishable from a human in its outward behavior, then I'd be forced to admit that it's as intelligent/conscious/sentient/whatever as a human, regardless of how it works internally. It's not like I make my friends take an MRI before I decide whether they're intelligent.

wasmperson··on Uber SubmitQueue: a high-performance speculative merge queue
Alternatively: don't worry about keeping trunk "green" at all. Have a second branch called "stable" or something that auto-fast-forwards to latest trunk whenever trunk is green. Checkout stable, push new changes to trunk, avoid breaking CI, but if you break CI then don't worry about it, just push up a fix.

If you act like trunk is this "sacred" thing that must always be ready to deploy then what you end up with is a bunch of long-lived branches and PRs and all the merge conflicts and overhead that come with those.

Page 1 of 4Next →