HNHacker News
TopNewBestAskShowJobs

jmmv

2,241 karma · joined December 31, 2013

https://jmmv.dev/ -- Contact me via julio@meroh.net or @jmmv.
submissionscomments
jmmv··on Building a Shell
Somebody blamed this comment on LLMs, and maybe/probably it is, but I think the first sentence is spot-on so I thought it was worth replying to.

Dealing with the corner cases ends up teaching you a lot about a language and for an ancient language like the shell, dealing with the corner cases also takes you through the thinking process of the original authors and the constraints they were subject to. I found myself in this situation while writing EndBASIC and wrote an article with the surprises I encountered, because I found the journey fascinating: https://www.endbasic.dev/2023/01/endbasic-parsing-difficulti...

jmmv··on Why I love FreeBSD
To be honest I've never tried boot environments. I know they are a thing, and I have my whole setup on ZFS, so maybe that's the perfect use case.
jmmv··on Why I love FreeBSD
> I delayed upgrading to 15.0 after it was released, but last weekend I finally did it, and it left me wondering why I hadn't done it sooner, because it went quickly and smoothly.

I haven't done that yet because I think I'd want to switch to pkgbase but that makes me nervous. Did you go with that option or continued to use the sets?

jmmv··on TUI Studio – visual terminal UI design tool
“Modern TUIs may support mouse events” hah! They already did in the 80s…
jmmv··on FreeBSD 14.4-Release Announcement
Huh, in a point release?

But excited to try it out ASAP! I haven’t made the leap to 15 on my server yet (in part because I can’t decide whether to go with pkgbase or not…), but sharing data more easily with VMs will surely be nice.

What’s the performance like?

jmmv··on When AI 'builds a browser,' check the repo before believing the hype
I don't disregard what you are saying and believe that being more productive with sufficient quality is _possible_.

But how do you measure it? All the metrics I see being chased (metrics that were never accepted as productivity measurements before) can be gamed with slop, and so slop is what we'll get.

jmmv··on When AI 'builds a browser,' check the repo before believing the hype
If we have been complaining about bloat before, the amount of bloat we are going to witness in the future is unfathomable. How can anyone be proud of a claim like "It's 3M+ lines of code across thousands of files." _especially_ when a lot of this code is relying on external dependencies? Less code is almost always better, not more!

I'm also getting really tired of claims like "we are X% more productive with AI now!" (that I'm hearing day in and out at work and LinkedIn of course). Didn't we, as an industry, agree that we _didn't_ know how to measure productivity? Why is everyone believing all of these sudden metrics that try to claim otherwise?

Look, I'm not against AI. I'm finding it quite valuable for certain scenarios -- but in a constrained environment and with very clear guidance. Letting it loose with coding is not one of them, and the hype is dangerous by how much it's being believed.

jmmv··on Huge Binaries
This is something that always bothered me while I was working at Google too: we had an amazing compute and storage infrastructure that kept getting crazier and crazier over the years (in terms of performance, scalability and redundancy) but everything in operations felt slow because of the massive size of binaries. Running a command line binary? Slow. Building a binary for deployment? Slow. Deploying a binary? Slow.

The answer to an ever-increasing size of binaries was always "let's make the infrastructure scale up!" instead of "let's... not do this crazy thing maybe?". By the time I left, there were some new initiatives towards the latter and the feeling that "maybe we should have put limits much earlier" but retrofitting limits into the existing bloat was going to be exceedingly difficult.

jmmv··on SSH-agent broken in tmux? I've got you
This is explained in the original article linked in the first sentence: https://blogsystem5.substack.com/p/ssh-agent-forwarding-and-...
jmmv··on SSH-agent broken in tmux? I've got you
The image? Yes. The text? Not at all.
jmmv··on From Azure Functions to FreeBSD
Thanks!

> I moved away from FreeBSD to Debian for hosting my things because the process/daemon management was too tricky.

It indeed is tricky. To be honest, I wasn't "put off" by it because I've been using BSDs and old-style Linux startup systems for almost 30 years now... but the lack of abstraction shows, and I don't think it's great.

The daemon(8) wrapper is neat to integrate pre-existing servers into rc.d, but I do not fancy having to deal with that "by hand" nor to create a shell script to manage my own service (related from a few years ago: https://jmmv.dev/2020/08/rcd-libexec-etc.html) nor to have something entirely separate to manage log rotation.

As much hate as systemd gets, I do think being declarative (and doing so in a DSL that's not a programming language) and having a true process "supervisor" is a better model. BUT, as I mentioned in this article, I also like the "no churn" of the BSDs because what I learned and refined over ~30 years is still similar to this day and that I won't be bitten by surprises.

jmmv··on Why xor eax, eax?
> It gets better though! Since this is a very common operation, x86 CPUs spot this “zeroing idiom” early in the pipeline and can specifically optimise around it: the out-of-order tracking systems knows that the value of “eax” (or whichever register is being zeroed) does not depend on the previous value of eax, so it can allocate a fresh, dependency-free zero register renamer slot.

While this is probably true ("probably" because I haven't checked it myself, but it makes sense), the CPU could do the exact same thing for "mov eax, 0", couldn't it? (Does it?)

jmmv··on Writing a DOS Clone in 2019
Yep, I thought so too! It’s a very interesting and fun topic.

So… I cannot resist redirecting you to a set of articles I wrote about two years ago on DOS and memory management, which I think covers some of the basic parts. The first one is https://open.substack.com/pub/blogsystem5/p/from-0-to-1-mb-i...

jmmv··on Let's Help NetBSD Cross the Finish Line Before 2025 Ends
Donated! I should have done this months ago when I started using NetBSD for an embedded project idea (that has gone nowhere).

But I feel this link illustrates a big problem with NetBSD’s “no hype” approach: I clicked the link you shared and found an email. The email has the donation link at the very end, and it’s not clickable. When I go to the donation page, there is a ton of text before I even get to see an ugly PayPal tiny button or a tiny form to donate via Stripe.

It’s too hard to notice and too hard to do. The project’s homepage does a better job though. But I think it should be made even more prominent if this is critical for the project’s health!

jmmv··on Let's Help NetBSD Cross the Finish Line Before 2025 Ends
That’s because… I misread your comment.

In any case, NetBSD is not well known and “why bother because Linux also runs everywhere too” so I thought it was worth explaining.

jmmv··on Let's Help NetBSD Cross the Finish Line Before 2025 Ends
That may be technically true but…

Linux (the kernel) may have been ported to more machines and architectures than NetBSD’s kernel, yes. But is all the code present in the same source tree or do you have to go find patch sets or unofficial branches?

More importantly: is there a modern distribution that builds an installable system for that platform?

The special thing about NetBSD is that you get the portability out of a single and modern tree for many more platforms than any single Linux distribution offers.

jmmv··on IDEs we had 30 years ago and lost (2023)
> Ok, this post is mostly about text-based IDEs, but I think the point mostly stands as well for IDEs in general. I'm thinking about Visual Basic or Delphi.

Exactly. I recently recorded a video of me creating a toy app with VB3 on Windows 3.11 and the corresponding tweet went “viral” for similar reasons as this article.

It’s not really about the TUI: it’s about the integrated experience as you say!

jmmv··on IDEs we had 30 years ago and lost (2023)
Hey, thanks for sharing this again! FYI, previous discussion from 2 years ago now (wow, time flies...): https://news.ycombinator.com/item?id=38792446
jmmv··on IDEs we had 30 years ago and lost (2023)
> it just uses conventions he is not used to

I think that after 25+ years of usage, I'm "used to it" by now.

jmmv··on SmolBSD – build your own minimal BSD system
BSDs do not break backwards compatibility (at least from what I know from FreeBSD and NetBSD). You _can_ disable backwards compatibility via kernel-level options and by not installing certain distribution sets -- but the default is to remain backwards compatible.

What being a kernel+userland helps with is in implementing features end-to-end: if you have to change how a certain aspect of the network configuration happens, you can do the kernel changes and the userlevel changes in unison. Which explains why you have a unique set of network tools, great documentation, a simple build system that can upgrade the machine...

jmmv··on SmolBSD – build your own minimal BSD system
If you like this, I'd also suggest reading on "Rumpkernels", which are also based on NetBSD. The core idea is (simplified): let's implement the kernel API in userspace so that we can take kernel-level components and run them as part of an application.

Rumpkernels then allow, for example, taking all file system drivers in the kernel and running them in userspace without having to rewrite all of the file system tricky logic. Think of "mtools" if you ever used them, but by reusing existing FAT code. Or making it trivial to create disk images from userspace without having to have special kernel primitives nor root access.

And also, they allow taking a userspace application and packaging it with the minimum set of drivers required to run "bare metal". Which is what the SSH example in the smol page brought to mind. See https://github.com/rumpkernel/wiki/wiki/Repo%3A-rumprun

jmmv··on Using a laptop as an HDMI monitor for an SBC
> digging up an HDMI monitor, finding somewhere to put it, and connecting it to the device is an annoying process. Furthermore, if I’m on the go I almost certainly don’t have easy access to an external monitor.

This has annoyed me many times as well with the headless computers I run... until recently, when I bought a USB-powered 7-inch HDMI monitor for an embedded project that didn't go anywhere. But now I have a spare little monitor that I can easily use in these situations and even carry it around if necessary.

jmmv··on Build files are the best tool to represent software architecture
> * Non-human intermediate targets would either be namespaced and available only in that namespace, or could be marked as hidden, and not clutter auto-completion

This is actually possible but you need the new JetBrains-owned Bazel plugin _and_ you need to leverage visibility rules. The latter are something that's unique to Bazel (none of the other language-specific package managers I've touched upon in these replies offers it) and are even harder to explain to people somehow... because these only start making sense when you pass a certain codebase size / complexity.

> * I thought C/C++ rules would generate .o files, and only the final cc_shared_library would produce an .so file > * Similar for .jar files

These are possible too! Modern Bazel has finally pushed out all language-specific logic out of the core and into Starlark rules (and Buck2 has been doing this from the ground up). There is nothing preventing you from crafting your own build rules that behave in these specific ways.

In any case... as for dynamic libraries per target, I do not think what I described earlier is the default behavior in Bazel (we explicitly enable dynamic libraries to make remote caching more efficient), so maybe you can get what you want already by being careful with cc_shared_library and/or being careful about tagging individual cc_libraries as static/dynamic.

For Java, I've been tempted to write custom rules that do _not_ generate intermediate JARs at all. It's quite a bit of work though, so I haven't, but it could be done. BTW I'll actually be describing this problem in a BazelCon 2025 lighting talk :)

jmmv··on Build files are the best tool to represent software architecture
You tend to end up with way too many targets that don't actually "mean anything" to a human. In one codebase I have to deal with, the Bazel build has ~10k targets whereas the previous non-Bazel build had ~400. Too many targets have an impact in various dimensions. Some examples:

* The build files are unreadable. If targets don't mean anything to a human, updates to build files become pure toil (and is when devs ask for build files to be auto-generated from source).

* IDE integrations (particularly via the IntelliJ Bazel plugin) become slower because generating metadata for those targets takes time.

* Binary debugging is slower because the C/C++ rules generate one intermediate .so file per target and GDB/LLDB take a long time to load those dependencies vs. a smaller set of deps.

* Certain Java operations can be slower. In the case of Java, the rules generate one intermediate JAR file per target, which has a direct impact on CLASSPATH length and that may matter when you do introspection. This tends to matter for tests (not so much for prod where you use a deploy JAR which collapses all intermediate JARs into just one).

jmmv··on Build files are the best tool to represent software architecture
In the article, yes. Look at the other comment threads in this discussion though: they touch upon many other languages.
jmmv··on Build files are the best tool to represent software architecture
No. The very first complaint is that if you don't know what is being used or not, you cannot tell whether a new "import" will add _another_ cross-module dependency that did not yet exist.

As I already mentioned in another comment, you have:

    .../module1/__init__.py -> import module3
    .../module1/foobar.py -> import module3
    .../module1/baz.py -> import module2
Now you are editing or reviewing a change to foobar.py. How can you tell if depending on module2 is conceptually OK? You need to look at baz.py to prove to yourself that the dependency already exists. Or you need to know a priory that it's an OK thing to do.
jmmv··on Build files are the best tool to represent software architecture
> One of the worst things a developer accustomed to Bazel (and its relatives) can do with a modern language (say Go or Rust) is to model code and organize it through the Bazel concept of a build target (https://bazel.build/concepts/build-ref) first

And that's exactly what I was arguing against in the article! I've seen this happen a few times already (in Java and TypeScript specifically) where Bazel's fine-grained target definitions are pushed as "best practice" and everybody ends up hating the results, for good reasons.

There are _different_ ways in which one can organize the Bazel build rules that go against those best practices (like the 1:1:1 rule for Java), and I think you can end up with something that better maps to first principles / or what native built tooling does.

jmmv··on Build files are the best tool to represent software architecture
I don't think the article talks about unused dependencies anywhere, does it?
jmmv··on Build files are the best tool to represent software architecture
> This is not true for Go, for example. Import statements absolutely do solve this problem in Go. I rarely need to ever look at module files which are in some ways a byproduct of the import statements.

Go imports still work at the Go package level. If you have multiple .go source files in one package, you have the exact same issue I described for Java.

    .../pkg1/foo.go -> import .../pkg2
    .../pkg1/bar.go -> import .../pkg3
If I'm editing / reviewing a change to pkg1/foo.go, I cannot tell that pkg1 _already_ depends on pkg3. Can I?
jmmv··on Build files are the best tool to represent software architecture
I have worked with ProjectReference before. How is it different from expressing a cross-module dependency in a Bazel BUILD file?

But as I already said in two other comments in this discussion, ProjectReference would be equivalent to what I'm describing in the article, just using language-specific tooling. If you are breaking your solution into various projects and keeping them separate with cross-references among them, you are doing exactly what I was describing already.

← PreviousPage 2 of 13Next →