assumed_throwaw
3 days ago
Tangential, but the complexity and over-head of the malloc abstraction is precisely what made me very intrigued by "stack-only" languages, such a recently published Goose. There is something very elegant and exciting about the idea of (almost) completely getting rid of it. Just as modern programming languages have developed good ergonomics that replaces a garbage collector, the same could hopefully be done to replace heap-allocated memory.
SkiFire13
2 days ago
> the complexity and over-head of the malloc abstraction is precisely what made me very intrigued by "stack-only" languages, such a recently published Goose.
Goose's stacks have quite some complexity themselves. They preallocate a ton of memory. The compiler has to magically match your code to each stack. You are not allowed to have nested growing types (e.g. creating an adjacency list is not so easy). And after all for some usecases you still end up using an allocator (Goose's linked list example ends up building a pool allocator for the linked list nodes!)
i2talics
2 days ago
If your takeaway from this was "wow malloc has so much overhead" then you may want to notice the part where they benchmark against glibc malloc and glibc is somewhere between 20-150x faster than their implementation. And that's fine, this exposition is basically what you would learn in an undergraduate systems programming course, but production allocators are able to significantly cut down the amount of work needed to grab an allocation, especially for small ones that occur frequently.
packetlost
2 days ago
> where they benchmark against glibc malloc and glibc is somewhere between 20-150x faster than their implementation
Where are you seeing that?
smashspectacle
3 days ago
This is actually what first drew me to zig. Most people talk about error handling, but the explicit allocator handling and making choosing an allocator a deliberate consideration has pushed me to better coding habits in general. I don't think it is possible or practical to completely abandon heap-allocated memory, but explicitly choosing between allocation types and styles that most precisely fit a job has great potential for meeting that spirit.
tremon
2 days ago
To me the value of zig's approach is in being able to control the allocations that happen in (library) code. When you call a C function, all kinds of heap allocations may happen between the callee and malloc, even if the return value of the call is in caller-allocated memory. With zig, you can pass a local (arena) allocator instead and avoid uncontrolled global allocations.
dreamcompiler
2 days ago
You can definitely avoid heap-allocated memory; early versions of Fortran could not do dynamic memory allocation at all. You basically had to preallocate giant arrays and build your own memory manager. It was sheer hell but it worked.
EPWN3D
3 days ago
I don't think we can get rid of heap memory, but I do think we can get rid of a shared heap.
tremon
12 hours ago
Isn't a shared heap pretty much the difference between multithreading and multiprocessing? Won't it turn every form of thread synchronization into a remote procedure call?
lawandjustice
3 days ago
[flagged]
eschneider
3 days ago
Embedded programming has taught me that almost anything can be a stack-only language if you want it to be, even C++. :)
connicpu
3 days ago
Avoiding the heap entirely isn't required and will prevent you from working with substantial amounts of data. The real key is to allocate all the memory you need up front and use that large block for a long duration.
packetlost
3 days ago
> Avoiding the heap ... will prevent you from working with substantial amounts of data
This isn't really true of Goose, it's avoiding 'the heap' in the C sense, not in the OS allocated pages of memory sense. One is a programming abstraction provided by the other, but GP is only talking about the programming abstraction. I have never encountered a program that couldn't have memory be explicitly tied to lexical scope, but it can result in less efficient use of it in some cases.
Goose is almost, but not exactly the "allocate all your stuff at the beginning" the programming language. It's honestly the most exciting language I've seen in quite some time.
dataflow
3 days ago
> I have never encountered a program that couldn't have memory be explicitly tied to lexical scope, but it can result in less efficient use of it in some cases.
> Goose is honestly the most exciting language I've seen in quite some time.
I took a look at its home page [1] and I immediately see red flags:
- Over sixteen benchmarks Goose runs at 3.3x the speed of idiomatic C++, 1.16x hand-optimized C++ and 1.12x the best safe Rust, and uses 1.9x, 1.3x and 1.2x less memory (results). These gains come from Goose's data layouts and memory model.
- push returns a reference to the new element, so a program can link elements while building the array. A vector<T> or Vec<T> may reallocate and cannot provide this guarantee. Stable references account for several benchmark gains.
You're suggesting a performance loss (as expected), but they're claiming a (rather incredible) performance gain?
And they're claiming their vector stable and doesn't reallocate, yet without a performance loss, which makes no sense... it's not a vector anymore. And if you want a non-vector then you can do that in C++ too.
The whole LLM vibe doesn't help inspire confidence either, but even ignoring that, the technical claims themselves are incredible and bizarre, and I'm only a few paragraphs in.
kbolino
2 days ago
It might be worthwhile to balance these positive claims against the language's own stated limitations [1].
Also, I took a closer look at the actual benchmark results [2]. For memory usage, at least, the median would show Goose using slightly more memory than the well optimized C++ and Rust. It looks like the mean is skewed in Goose's favor by a couple of benchmarks where it does extremely well due to its variable-length enums.
[1]: https://aardappel.github.io/goose/docs/tutorial.html#18-limi...
Someone
2 days ago
> You're suggesting a performance loss (as expected), but they're claiming a (rather incredible) performance gain?
I think part of the reason they’re getting higher performance is that they accept higher memory usage. Memory can be ‘freed’ later than in traditional languages, and the combined size of all stacks will be larger (maybe even much larger) than maximum memory usage.
The language likely also has limitations in that some constructs are hard or impossible to express (similar to how Rust has memory safety safer, but pays for it by having problems implemented doubly-linked lists)
senderista
2 days ago
I just want to point out that the author of Goose has plenty of technical cred, having authored flatbuffers and lots of other cool stuff.
dataflow
2 days ago
That's great, but it doesn't explain anything I'm seeing. I'm just commenting on the (presentation of) the project. It's entirely possible they have something awesome that just isn't presented well, or that I'm just too dense to grasp the awesomeness of what's before me. Whatever it is, I'm just saying I can't make sense of what I'm being sold.
packetlost
2 days ago
Goose is a weird language. It uses a pile of pre-allocated datastacks, enforces lexical lifetimes for all data, and has first-class syntactic support for capped, growable, and shrinkable arrays. It also spits out a pile of C that gets all the optimization benefits of <insert C compiler of choices>.
Goose in particular excites me because I have done similar design work over the years.
nialv7
3 days ago
the stack is just a bump allocator. the unique thing about stack-only languages is lifetime management, not really how they allocate.
saagarjha
3 days ago
A stack only language that called into malloc to service allocations would not be very interesting.
jacquesm
3 days ago
Most stack oriented languages also have a heap.
chemodax
2 days ago
In my opinion pools are the best concept for unmanaged code.