Hacker Newsnew | past | comments | ask | show | jobs | submit | smj-edison's commentslogin

I've tried to use Claude Code with Sonnet 4.5 for implementing a new interpreter, and man is it bad with reference counting. Granted, I'm doing it in Zig, so there's not as much training, but Claude will suggest the most stupid changes. All it does is make the rare case of incorrect reference counting more rare, not fixing the underlying problem. It kept heaping on more and more hacks, until I decided enough is enough and rolled up my sleeves. I still can't tell if it makes me faster, or if I'm faster.

Even when refactoring, it would change all my comments, which is really annoying, as I put a lot of thought into my comments. Plus, the time it took to do each refactoring step was about how long it would take me, and when I do it I get the additional benefit of feeling when I'm repeating code too often.

So, I'm not using it for now, except for isolating bugs. It's addicting having it work on it for me, but I end up feeling disconnected and then something inevitably goes wrong.


I'm also building a language in Zig!

Good luck!


Oh cool! I'd love to hear more. I'm implementing an existing language, Tcl, but I'm working on making it safe to share values between threads, since a project I contribute to[1] uses Tcl for all the scripting, but they have about a 30% overhead with serialization/deserialization between threads, and it doesn't allow for sharing large values without significant overheads. I'm also doing some experiments with heap representation to reduce data indirection, so it's been fun getting to learn how to implement malloc and other low-level primitives I usually take for granted.

[1] folk.computer


It's important to distinguish between the Framework 13 and the Framework 16. The Framework 16 is by far the most ambitious of the two, and so it has had a lot more issues. I use a Framework 13, and I've loved it. It's light, has a solid frame, and runs Linux great. The battery life isn't great, and the speakers aren't either, but I've been able to mitigate the latter with EasyEffects.

It's also really ergonomic with `errdefer` and `try`.

Gilad Bracha talks about how they're not mutually exclusive concepts, and I mostly agree (OOP can have tailcall recursion and first order functions for example). But, the philosophy seems very different: functional programming is "standing above" the data, where you have visibility at all times, and do transformations on the data. OOP is much more about encapsulation, where you "send a message" to an object, and it does its own thing. So you could totally write OOP code where you provide some core data structures that you run operations on, but in practice encapsulation encourages hiding internal data.

Though on further thought, may be this isn't FP vs OOP, because C has a similar approach of "standing above", and C is the hallmark imperative language.


As long as you keep C pointers as pointers. The mutable aliasing rules can bite you though.

> Keep in mind that Go was created before we knew how to make actually dynamically-typed languages fast.

Would you mind elaborating on this? The strongtalk heritage of VMs has been around for a while now, and certainly before go was started.


In Zig's case, the entire stdlib never allocates on failure, and most libraries follow the same pattern. The philosophy of Zig is allocation/creation can fail, but freeing/destroying must never fail. It's caused me to be really thoughtful with how I design my data structures, and often made me use better ways of representing metadata.

How do you log or tell the world about the state of the program without allocating?

Well if you've hit OOM, you're kinda screwed anyways. But, if you allocate a ring buffer at the beginning, you can always do a best attempt write.

Why screwed? It could just be that there is more load than your application can handle. Why should it necessarily crash because of that?

Maybe screwed was too strong of a term. In the scenario above, they wanted to log on resource cleanup, but that makes resource cleanup potentially fallible. The Zig philosophy is that cleanup must never fail, so having cleanup be fallible goes against that.

I was suggesting (though in retrospect not clearly) that logging should use a ring buffer instead of allocation, in order to make logging on cleanup a guaranteed best effort operation. You're right that you can recover from OOM, but logging OOM with an allocator is pretty self-defeating.


You need to apply backpressure before you hit memory limits, not after.

If you’re OOM your application is in a pretty unrecoverable state. Theoretically possible, practically not.


If you allocate a relatively big chunk of memory for each unit of work, and at some point your allocation fails, you can just drop that unit of work. What is not practical?

I think in that case overcommit will happily say the allocation worked. Unless you also zero the entire chunk of memory and then get OOM killed on the write.

I suppose you can try to reliable target "seriously wild allocation fails" without leaving too much memory on the table.

   0: Heuristic overcommit handling. Obvious overcommits of
      address space are refused. Used for a typical system. It
      ensures a seriously wild allocation fails while allowing
      overcommit to reduce swap usage.  root is allowed to 
      allocate slightly more memory in this mode. This is the 
   default.
https://www.kernel.org/doc/Documentation/vm/overcommit-accou...

Running in an environent without overcommit would allow you to handle it gracefully though, although bringing its own zoo of nasty footguns.

See this recent discussion on what can happen when turning off overcommit:

https://news.ycombinator.com/item?id=46300411


> See this recent discussion on what can happen when turning off overcommit:

What are you referring to specifically? Overcommit is only (presumably) useful if you are using Linux as a desktop OS.


Good grief all kinds of ways. Practically all the same countless possible paths as those that require allocating.

You don't have to allocate to print to stdout if that's what you're asking.

And then whatever thing that is collecting and forwarding(if applicable) the logs needs to be entirely allocation free?

It just needs to have whatever memory it needs statically allocated.

Interesting, what causes the speedup?

You can skip some bounds checks and then get 50% slower because the hardware is not very powerful

How did you get Fusion 360 running? I've tried multiple times but it always gets stuck at the installer.

I don’t think he did get it running. It’s one of my main blockers as well. Last time I tried I got as far as it starting up and logging in to their identity server via the browser, but the redirect back to the application didn’t work. Such a silly thing that prevents it from working. Why does a CAD program need to online auth, anyway? (I know the reason but it’s an annoying one)

As the other poster imagines, I didn't. I could write a blog post about the 3 days I spent with Claude trying everything, different wine variants, patched WebView2.exes, container types, x11 vs wayland, logging in on a vm and copying credentials, intercepting calls to and from the fucking web view, GPU pass through for dedicated vms using iommu and virtio, what a mess. I don't want windows on a hard drive but it's that or use my work MacBook which is kind of a non starter for obvious reasons at this point.

Funny thing is it worked on my old popos install and I backed it up... But a lot of the home dir wine prefix stuff was symlinks to var or opt or something which of course my dumb ass didn't backup. Monthly 60gb homedir backups without the one thing I wanted smh


Ah, my bad, I misread your post :)

> Rust makes it possible to safely manage memory without using a garbage collector, probably one of the biggest pain points of using low-level languages like C and C++. It boils down to the fact that many of the common memory issues that we can experience, things like dangling pointers, double freeing memory, and data races, all stem from the same thing: uncontrolled sharing of mutable state.

Minor nit: this should be mutable state and lifetimes. I worked with Rust for two years before recently working with Zig, and I have to say opt-in explicit lifetimes without XOR mutability requirements would be a nice combo.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: