News for hackers. Stuff that matters.

Aardappel

Haha, I thing "Bla" was probably one of my least successful designs! So elegant, but too weird? Anyway, glad you remember :)
Because you really can't do all the static checking and convenience like that with a library.

As for the benchmarks, that's exactly what I do: https://aardappel.github.io/goose/bench/results.html

If you mean the other benchmarks (LangArena), I don't control their design.

C++ code that does what Goose does is a soup of pointer manipulation, casts and byte stuffing. You could write that, but Goose proves it to be safe at compile time, with simple readable code. The moment you write "reasonable" code in C++, it is actually a lot slower than Goose.

For details on how, see https://github.com/aardappel/goose

No, I don't see how that would be. It will map process address space to physical memory just like other programs. Physical memory is already not guaranteed to look anything like your process address space, and that is not a problem (for caches, or anything else).
The runtime is not particularly complex, but making it run with no runtime would still take some doing :)

You'll have to explain what you mean exactly by "dynamically sized moves and struct members".

Haha small world :)
I guess Goose is closer to Rust and C/C++ in design, and removing it does introduce some parsing gotchas.

I guess people also differ by how much they are bothered by it :)

My other language, Lobster, has no semicolons at all :)

The function values are just compile time, not runtime. It has great support for higher order functions and other functional patterns (map/filter etc)
Sure, those cases could bite. I think all my benchmarks (and external benchmarks) are mostly single threaded.

Note that all this supposed copying overhead also has an upside: once the synchronisation has happened, every thread can now run at maximum speed doing single threaded memory allocation with no locking of any kind.

In C++, malloc/new in multithreaded programs needs to essentially go thru a mutex and can make allocation even more expensive than it already is. I am not sure if Rust does the same.

Since in Goose "allocation" is just a pointer bump, we cannot make that multi-threaded, hence the threading model followed from that.

And like a lot in Goose, you have to write your program to fit the language a bit. If you expect to do concurrency on top of a huge graph of constantly changing data that all threads must have immediate access to, it is probably not the language for you. But there are plenty of concurrency models that fit and are blazingly fast.

I generally LOVE concatenative languages! I made this once: https://strlen.com/false-language/
As I mention at the end of https://github.com/aardappel/goose/blob/master/README.md I essentially had it use a previous compiler of mine (Lobster) as a template.

Even if you don't have such an example, pick a project that you think has "good code" (even if it is not your own), point the LLM at it, tell it to have a deep read of the code, and come up with a very in-depth coding guideline in a .md file with code patterns etc. Then put that .md in your new project and tell it to follow it.

Thanks! There is certainly a big overlap with Rust in use cases.. I'll leave people to decide which they want to use :)
No, not yet. You can also change that amount if you want, just 2GB is a pretty optimal default.

I am not sure what issues could be caused by the sparsity. Like you say, all that matters is that in physical memory, we are only using what is actually in use.

Thanks! :)

Shared data structures accessed concurrently by multiple threads, yes.

Goose's thread system however has typed queue's inspired by the Linda Coordination Language https://en.wikipedia.org/wiki/Linda_(coordination_language) that can most definitely model some interesting data structures.

Re:The Goose Programming Language on Sunday October 25, 2026 @02:05AM (#50228772)
Yup that's how it works. Goose runs great on Windows. Yes, it be very tight to make work on 32-bit. DLLs definitely possible, most Goose programs only use a fraction of the 64-bit address space.
Sadly these memories are accessed thru a constant in the load/store instructions, and Goose would need this to be dynamic (since you can have code that processes pointers coming from multiple different stacks).
To run well, it doesn't just need wasm64 (which I worked on btw!) but it also needs the wasm64 memory to not commit until touched, or have a feature that allows Goose to do that. That and larger total memory. I pushed for that a while ago but I don't think it is possible today.
Have you seen the way Goose does threads? It's actually pretty close to what you're talking about: https://aardappel.github.io/goose/docs/reference.html#22-thr...
I've been making languages all my life, and I made this one because I had a really strong design in mind that I think should exist.

Whether it would make sense in this AI world was not a consideration.

The syntax and semantics were mostly designed for humans. That said, using it optimally asks a lot of the human, and in turns out the better LLMs don't break a sweat using it, so maybe it accidentally hits the spot. Goose with LLM can give you lots of speed without the effort.

In some weird way it is a great time to make new languages, because the downside of convincing humans to learn it is gone. Anyone that has a project that needs to be fast can decide to use Goose for it at very little cost.

It does not currently offer automatic AOS -> SOA transform, you'd have to do that yourself. I did look into it, but doing it automatically is not a great fit with how Goose tracks arrays. Maybe can be reconsidered at some point.
Thanks, that brings me back, haha :)
Good question, not sure without testing. Likely it will still give the error. It could elide it, but I am not sure how useful that is.

Optimized builds go thru the local C compiler, so they are limited by the speed of that. Dev/test build can use the built-in libtcc JIT which is super fast.

Haha yes, haven't updated my website in a while :(
Hah cool, small world :)
The language has different levels of solutions for the inner arrays being dynamic, for example a) only dynamic upon construction, b) fixed size, c) fixed size with cap, or d) allocated in a pool in a different array.

Depending on your needs you use one of these solutions.

Almost all languages rely on reallocation when a growable array grows, which means you can't store pointers to elements, as they get invalidated upon a reallocation.

In Goose, things grow in-place only, since they have a large amount of address space reserved.

Older »