HN user

nh2

3,528 karma

https://github.com/nh2

[ my public key: https://keybase.io/nh2; my proof: https://keybase.io/nh2/sigs/Duv6hcXOkjZU5KWzJ8d01yeD7QKmhG9QpVMOb4ZMkeU ]

Posts22
Comments704
View on HN
bugzilla.mozilla.org 2mo ago

Thunderbird donation page consumes CPU/GPU due to animation

nh2
4pts0
bugs.launchpad.net 2mo ago

Ubuntu Chromium Snap prevents encrypted storage of passwords by default

nh2
4pts3
github.com 1y ago

Vdu_controls – automatically control external monitor brightness on Linux

nh2
2pts1
mazzo.li 1y ago

Inline-Verilog: Execute Verilog circuits from Haskell

nh2
10pts0
news.ycombinator.com 1y ago

Ask HN: Challenge: Can code AIs fix real-world problems?

nh2
6pts1
issues.chromium.org 1y ago

Chromium uses web search for .internal TLD instead of opening URL

nh2
116pts85
github.com 1y ago

Just want simple TLS for your .internal network?

nh2
246pts143
github.com 3y ago

The Haskell job market has been growing steaily since 2008

nh2
134pts169
github.com 4y ago

Two minutes of CAPTCHA on google.com

nh2
2pts1
papercups.io 4y ago

Papercups (YC S20) open-source chat tool is now in Maintenance Mode

nh2
1pts1
github.com 5y ago

Corrupt Signal DB issue crashing App and losing data

nh2
119pts75
github.com 6y ago

Windows desktop GPU memory leaking into Linux screenshare app

nh2
3pts6
github.com 7y ago

Gmail spam-filters Stripe security messages as well

nh2
141pts95
github.com 7y ago

Gmail spam-filters PayPal security messages

nh2
74pts59
sourceware.org 7y ago

Glibc: realloc() ncopies 32-bit integer overflow

nh2
4pts2
forum.asrock.com 7y ago

ASRock motherboard destroys Linux software RAID

nh2
226pts88
blog.ptsecurity.com 8y ago

Intel patches new ME vulnerabilities

nh2
633pts327
github.com 8y ago

Debugging across pipes and sockets with strace [pdf]

nh2
111pts11
github.com 8y ago

Storing billions of lines of code in Git on a laptop

nh2
4pts0
news.ycombinator.com 9y ago

Is CloudFront down?

nh2
5pts2
serverfault.com 10y ago

Cron on Ubuntu silently truncates commands to 999 characters

nh2
5pts5
bugzilla.mozilla.org 11y ago

Thunderbird XMPP wizard silently ignores “Force encryption” setting

nh2
5pts2

The UNIX pipe has the (for many systems) undesirable negative property of losing data in the pipe when the receiving process terminates: Anything in the kernel buffer of the pipe gets lost.

Since the pipe is generally unidirectional, the sending process has no way of knowing whether the receiving process has received, or even more successfully processed, anything sent. For that, one needs to make a pipe in the opposite direction and that is not as easy anymore; it also requires building your own protocol to identify and acknowledge sent work items.

Another side remark:

LLMs removed some of the difficulty of Haskell, e.g. some interesting ideas to make things safer with sophisticated types or mechanisms like TemplateHaskell are now MUCH easier to implement in a few minutes. Also Haskell's general stance of breaking backwards compat in fundamental places if it's needed to make the language better, thus causing moderate amounds of upgrade grind, completely evaporated as a drawback because LLMs are extremely good at fixing type errors to bring code up to date with the latest changes.

The LLMs are very good at explaining Haskell compile errors.

Learning Haskell and maintaining projects in it is now easier than ever.

Hey, we have a 10 year old Haskell/Python/C++/TypeScript/Nix codebase, and use all of them regularly.

Haskell compiles slowly, but we have not found that to significantly inhibit AI-supported dev so far. We use ghci with `-fobject-code`, and our largest leaf module (10k lines of webserver request handlers) takes 8 seconds to `:reload`. To run stuff in it, the agent pipes `:reload`, or other invocations, into `ghci`.

Working on parts parts that are early in the module chain, such as our Prelude, makes the whole-project `:reload` take 50 seconds. Much of that could be avoided if we didn't suffer from the TH recompilation problem (https://gist.github.com/nh2/14e653bcbdc7f40042da3755539e554a). Originally I made a small GHC patch to hack that out (what this conservative recompilation protects from cannot happen in our project), which made the reload much faster, but the logic was changed in recent GHC so that doesn't work anymore.

In C++, we have some individual files (and thus compilation units) that take 45 seconds to compile.

Python is of course the fastest to (build+run). However, Python also has some problems with repeated runs: Once you have many imports, just starting the program (e.g. `--help`) takes ~2 seconds resolving imports. Do `import pytorch`, add another 2 seconds. For repeated runs, this can be a pain; Haskell and C++ are much faster for that, so they win when you don't have to change the code but repeatedly use already-compiled tools in a different way.

In all 3 languages, getting things to typecheck is very fast, because the agent directly reads the vscode LSP typechecking errors which are < 1s feedback. Claude Opus 4.6-4.8 understand all 3 languages very well.

I agree that GHC devs should focus most of their efforts on compile speed, and real-world pain solving. Some parts of that are indeed being done (e.g. newest GHC can write bytecode to disk to make the above workflow much faster, and codegen is by far the slowest part of compilation). But I think the focus should be even more on that. I consider most important and unsolved:

    * solving Generics being slow to compile, especially for types with many constructors
    * solving deriving classes being slow to compile
    * solving TemplateHaskell causing too much recompilation
    * doing staged compilation,
      so that the next module can typecheck as soon as its imports are typechecked,
      as opposed to waiting that codegen is done;
      this unlocks a large amount of parallel work availability
All of these have open GHC tickets that I think should be the highest focus.

Other real-world production things are being solved quite nicely currently:

    * The new Haskell debugger
    * Much better stacktraces
    * Much better runtime introspection to debug runtime hangs etc
I get your general point that if iteration speed (as in change code + run, 100s of times a day) is your highest value, Python does quite well. We intentionally chose Python for the part of the codebase that's relatively simple data importing but from 50 different sources, count growing adding new sources all the time, and need just quickly iterate on each until we got it.

But I find it would not be a great language for the other parts. Its concurrency story is bad, its interpreter is very slow and immediately disqualifies Python when you need to do e.g. a line of code for every 1000 Bytes (say for streaming small data chunks), typing is very useful but bolted-on and not always correct.

Things where Haskell remains best-in-class is anything nontrivial-webservers, I/O, program correctness, the main "general purpose" programming, refactoring and long-term maintainability.

I have 4 OpenWRT Ones and they are good.

If you just want a good WiFi router or access point, unless you need something cannot do (e.g. WiFi 7 or 10 Gbit/s Ethernet), and if want to spend minimal time messing around with routers today and in the future, just get this one.

After getting this, I see no reason to ever buy any closed-source router again.

No need to learn/remember any other Router config either. It's just all OpenWRT, always looks the same, always works the same. Setting up a new one takes me 2 minutes max.

The recent OpenWRT update also brought the one feature the project was most sorely missing: A simple "Download and install latest firmware" button in the device UI.

Now they just need to add an unattended-upgrades option and I never have to log in again after initial setup.

Note that's somewhat out of date:

`bin/switch-to-configuration` is a Perl script from the beginning

Since NixOS 24.11 the default is `switch-to-configuration-ng`, in Rust. That is a 2.8 MB binary, compared to NixOS's 55 MB Perl distribution. Thus such Perl-less systems shrunk that dependency by 20x regarding activation switching.

And since NixOS 25.11, `nixos-rebuild-ng` in Python replaces its former Perl counterpart, see https://wiki.nixos.org/wiki/Nixos-rebuild

Seems to me that such boolean flags do not force you to think about "building up" or "building down". You just declare what _is_. Who cares what the default is? When you're building a minimal thing, changing some defaults is fine.

I've been using SwiftKey for 10 years (typing not swiping), and test ran FUTO for the last month.

FUTO improved a lot (I had tried it a year earlier also) but SwiftKey's suggestions are still a lot better in my opinion. With SwiftKey I can just type roughly in the right spot without looking and the correct words will come out most of the time. FUTO still suggests a lot of nonsensical next words that just do not follow after the previous in English.

I hope it improves further so I can switch.

The voice models are great though, and they can be used as part of the keyboard or standalone.

Would you mind sharing a link to one of the open source project you've been maintaining and reviewing contributions on for years

Github is in my profile; I am nixpkgs committer for ~10 years (which is one of the most active projects on Github with 450000 merged PRs).

There is no way I could have possibly written and (pre-tested, to arrive at the eventual code submitted) all the code that I have reviewed.

From the other side, I have spent thousands of hours debugging and writing PRs to over 100 FOSS projects (e.g. glibc, busybox, util-linux, lz4, GHC and tens of Haskell packages, Jenkins, Chromium, GTK, Consul, OpenCV, Signal, many more).

Many of them are small or medium fixes ("drive-by fixes"), where you propose a PR, the owner reviews, says "great, thanks", and the bug gets fixed.

This is a fundamental workflow for open source work. The project gets free contributions and time investment outsourced to "the community" who fix its bugs, the developer-users/community get their problems fixed upstream, permanently.

This not possible for projects that don't have an easy way to submit code with low effort for both sides.

Accepting drive-by fixes is what clears up developer time and helps clear out the countless small issues in software.

If AI slop PRs are a problem, it seems better to establish clear rules and reject contributions that don't follow them with a single click, rather than banning developer contributions altogether. It seems to work acceptably for nixpkgs so far.

You can still submit a bug report and tell them exactly how you did it.

Can you? The announcement says "There will not be a separate process for submitting patches by other means. We do not want to create a shadow contribution system through issues, comments, email, or forks".

So I, as a human, describe in prose which changes I made to e.g. 20 files?

How is that in the spirit of fighting LLM slop?

Also, if I can do that, the LLM slop contributers can also ... do that.

There will not be a [..] process for submitting patches by [any] means

Outside involvement still matters: clear bug reports

So I can find a bug, I can fix it, but I am not allowed to tell them how exactly I did it.

Instead they have to re-figure it out. The team must be thrilled to re-do work they know was already put in by others, repeatedly.

As a user-and-eveloper, why would I sink time into a project with such rules that put a barrier to improving my life with the software? It seems much easier to use Firefox or Chromium, where my fixes actually meet open ears.

It was very useful for me in the past when a new Chromium version crashed on my product, that I could go and suggest a fix to V8, and it was rolled out in the next Chromium release so my product worked again (https://github.com/v8/v8/commit/4f8a70adca01c). Without this, maybe Chromium developers would have never bothered to fix it because of lack of time to figure it out.

a pull request no longer tells us as much as it used to about the person submitting it

Nobody should need to know anything about any person submitting a pull request. Hopefully whether code that makes it into Firefox or Chromium was never based on the "effort" or "faith" of the submitter, but based on the correctness of the code in review.

Reviewing code fixes is strictly easier than coming up with them yourself.

This holds true automatically: In any situation where it isn't, you can just write the code yourself and done.

As a project you can always ignore or close a PR you want to write yourself instead. But it seems unwise to bar yourself from the _option_ of reviewing an outside contribution, or using it as input for your own re-write.

In contrast to Microsoft, OpenAI, and Anthropic, AWS has never done anything close to sneaking in unwanted training opt-outs after the fact.

They are the only ones I trust not to do that so far. And their terms are extremely clear on that, no fuzzy language. Exactly what we want to see. So we use Bedrock.

No, this is not the reality of using Haskell packages.

The problem you describe was solved more than a decade ago.

You use a Stackage snapshot (https://www.stackage.org/lts) which is a curation of packages that work together, similar to a Linux distribution like Debian, carrying one version per package.

Our company using Haskell has not spent 1 minute doing "dependency resolution" in the last 10 years, not has anybody we know.

Asking the grandparent:

The what is the idea behind the "ideally have already read the paper, but given 10-20 minutes in silence" part?

The fact that people that have already read it have nothing to do and waste time sitting around bored sounds like an obvious flaw, are we missing something?

Even then, I also share the confusion of the poster you're replying to.

I don't see how a virtualised NVMe disk is different from a physical one.

Especially if you don't have control over the underlying hardware (so you don't know if it has power-loss-protection PLP SSDs), you should send the FUA.

O_DATA_SYNC

You mean `O_DSYNC`?

Why would you need `O_DSYNC` on-premise, but not on cloud VMs? (Or are you saying you'd include it everywhere?) Similar to my above point, surely it is the task of the VM to pass through any FUA commands the VM guest issues to the actual storage?

Further: Is `O_DSYNC` actually substantially different from writing and then `fdatasync()`ing yourself?

My understand is that no, it's the same. In particular, the same amount of data gets written. So if you believe that to avoid the "can trigger an order of magnitude more I/O" by avoiding `fdatasync()`, you would re-introduce it with `O_DSYNC`.

However, I suspect that that whole consideration is pointless:

The only thing that makes your O_DIRECT+preallocated-only-overwrites writes safe are enterprise SSDs with Power Loss Protection (PLP), usually capacitors.

On those SSDs, NVMe Flush/FUA are no-ops [1]. So you might as well `fdatasync()`/`O_DSYNC`, always. This is simpler, and also better because you do not need to assume/hope that your underlying SSDs have PLP: Doing the safe thing is fast on PLP [2], and safe on non-PLP.

    [1] https://news.ycombinator.com/item?id=46532675
    [2] https://tanelpoder.com/posts/using-pg-test-fsync-for-testing-low-latency-writes/
So the only remaining benefit of `O_DSYNC` over `fdatasync()` is that you save a syscall. That's an OK optimisation given they are equivalent, but it would surprise me if it had any noticeable impact at the latencies you are reporting ("413 us"), because [2] reports the difference beting 6 us.

Let me know if I got anything wrong.

The only remaining question is: Why do you then see any difference in your benchmark?

    Configuration            Throughput (obj/s)
    -------------------------------------------
    ext4 + O_DIRECT + fsync             116,041
    Our engine                          190,985
That is what I'd find very valuable to investigate.

The first suspicion I have is: Shouldn't you be measuring `+ fdatasync` instead?

So I'd be interested in:

    ext4 + O_DIRECT + fdatasync
    ext4 + O_DIRECT + O_DSYNC
    Our engine + O_DSYNC (which you're suggesting above)
Also I don't fully understand what the remaining diference between "ext4 + O_DIRECT + O_DSYNC" and "Our engine + O_DSYNC" would be.

fsync doesn’t just sync the file’s data, it syncs every piece of metadata the file depends on: ... directory entry

Famously not, as the man page says.

It is also said later in the article:

POSIX strictly requires a parent-directory fsync to make a newly created file’s existence durable.

So I'm not sure why the dirent sync is claimed earlier.

Given the commit is 4 weeks old, will it eventually get comments?

The code before the patch does not look obviously wrong. Now, some more lines were added, but would you now say it now looks less obviously wrong, or more obviously correct?

It seems that the invariants needed here are either in some person's heads, or in some document that is not referenced.

Reading the code for the first time, the immediate question is: "What other lines might be missing? How can I figure?"

If the "obviously correct" level of the code does not increase for a human reviewer, how is it ensured that a similar problem will not arise in the future? Or do we need more LLM to tell us which other lines need to be added?

Ubuntu ships a Chromium browser that has its abilitiy to store passwords safely sandboxed/containerized away.

I did not expect that, given that Ubuntu comes with a full GUI and thus safe password storage backend available in theory.

Because this issue is open since 2022, I wrote a repro that proves its existence:

https://bugs.launchpad.net/ubuntu/+source/chromium-browser/+...

All credit goes to user "Erlenmayr" who reported this.

Zed 1.0 3 months ago

That does not really matter though: Even immediate-mode approach programs should just not be drawing new frames when the program logic says that there are no new inputs that can result in different pixels (e.g. no user inputs, animations, notifications, text content changes, etc.). One does not need to "poll" for input.

Copy Fail 3 months ago

Indeed, no modprobe.d will help when the feature is compiled into the kernel ("=y") instead of compiled into a runtime-loadable module.

Copy Fail 3 months ago

If you want to use the suggested mitigation (disabling kernel module `algif_aead` with a modprobe config), and you do not want to run that whole obfuscated shell code to get an actual root shell, but only check if the module can be loaded, here is a readable version of its first few lines:

    python3 -c 'import socket; s = socket.socket(socket.AF_ALG, socket.SOCK_SEQPACKET, 0); s.bind(("aead","authencesn(hmac(sha256),cbc(aes))")); print("algif_aead probably successfully loaded, mitigation not effective; remove again with: rmmod algif_aead")'
Similarly, when the mitigation is in place,
    modprobe algif_aead
should fail with an error.
Zed 1.0 3 months ago

Can you repro my finding?

I'm running on a Zed with only 1 empty text file in it. So language servers should not be in use.

How do you measure "pretty lightweight"?

Copy Fail 3 months ago

On a git repo that has as remotes

    https://github.com/torvalds/linux.git
    https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git as remotes:
running a search for commit a664bf3d603d's commit message:
    git log --all --grep 'crypto: algif_aead - Revert to operating out-of-place' '--format=%H' | xargs -I '{}' git tag --contains '{}' | sort -u
outputs these tags as having the fix:
    v6.18.22
    v6.18.23
    v6.18.24
    v6.18.25
    v6.19.12
    v6.19.13
    v6.19.14
    v7.0
    v7.0.1
    v7.0.2
    v7.0-rc7
    v7.1-rc1
Zed 1.0 3 months ago

I have not lost any Sublime tab in 15 years (I have tabs this old).

Sublime also saves a backup of its state files next to the state files in your home dir, so you can restore in case anything ever goes wrong (e.g. bugs in the new version).

The .sublime_session state files are JSON, easy to read for a human.

spending an hour making up names for random junk files

That is completely unnecessary. You can just backup the '.sublime_session' file that contains all that before an upgrade if you are worried. Sublime already stores all its state in 1 file; manually spreading that across N files seems unfun busywork. A quick web search reveals that by the way.

(I perpetually have 40 Sublime windows open, each one with tens to hundreds of tabs. My 'Auto Save Session.sublime_session' is 70 MB.)