Top
Best
New

Posted by bobbydigitales 14 hours ago

The Goose Programming Language(aardappel.github.io)
https://twitter.com/ID_AA_Carmack/status/2113704269274636568
364 points | 240 commentspage 2
Aardappel 12 hours ago|
I made the language, AMA :)
pixelesque 11 hours ago||
Without wanting to be snarky, are the "hand optimized" C++ benchmark files mentioned on the benchmark page available anywhere, as the ones in the "bench/cpp/" directory don't look that optimized to me?

e.g. I see a general lack of reserve()s on strings and vectors (a few tests do use them a bit, like `graph` and `particles`), and there are several other things which I wouldn't personally call "optimized", so I assume those ones are the 'idiomatic' ones?

Same goes for the Rust code: a lot of the code seems to be using Vec::new() and String::new(), instead of ::with_capacity() which would optimize the memory re-allocation (reducing it as the containers/strings grow).

Aardappel 11 hours ago||
Yes indeed, the real hand optimized files are private, the ones in the repo are decoys.
dbdr 3 hours ago|||
Why?
dash2 11 hours ago|||
Do you think it would be worth writing the landing page yourself? The concepts seem interesting but it's painful to wade through stuff like "One memory model: stacks, and scope exit is the free".
Aardappel 11 hours ago||
I've already edited it plenty, but I guess it doesn't bother me that much.

I preferred people being able to play with it rather than worrying about any claude-isms :)

onlyrealcuzzo 11 hours ago|||
If you mentioned it in the main page, I didn't see it.

Something that I'm interested in: How fast is the compilation speed on large programs compared to Zig, C, Go?

My ideal language is safer than Rust (no deadlocks / livelocks, no stack overflow from recursion), is optimized for cache locality, but compiles faster than Zig.

This seems like it's close to 2/3.

Aardappel 11 hours ago||
The current implementation goes thru an optimizing C compiler as backend for "shipping/production" builds, which will limit how fast we can make it compile.

That said, during development/iteration/testing, you can just the built-in JIT, which is based on libtcc (which is very fast), as don't as you don't mind a ~3x runtime slowdown.

jnpnj 11 hours ago|||
Was it your first programming language ?

ps: Ah well, I could have searched before asking https://strlen.com/programming-languages/

super neat history !

Aardappel 11 hours ago||
Haha yeah no, I'm afraid I keep making new ones! :P
briandw 11 hours ago||
Fantastic project BTW! How much AI help did you have with this project? I'm assuming some. If so is it something that you would have taken on before AI help?
loufe 11 hours ago||
There's a section at the bottom called "History & Use of AI". Please do your part to keep the discussion here honest and healthy, if not a read of the post, at least a ctrl-f would have been sage.
weinzierl 13 hours ago||
Rust's appeal (to me) is safety, performance, DX in that order.

Where does Goose sit when classified along these dimensions?

Sure, performance is right there on the packaging but no word about UB in the README. I read "Goose has syntax familiar to C and Rust" as DX in the same ballpark, but is it a performance first or safety first language.

If it is the former it occupies the same crowded niche as C++ and its many cousins and will have a hard time.

If it's the latter it will have much more room to prosper. We don't have enough languages in the niche that Rust and Ada fill right now.

Aardappel 10 hours ago||
Goose has no "unsafe" feature, and no undefined behavior, and is fully memory safe.

It is obviously has a lot of potential to be very fast.

It even does pretty good on DX. There is no borrow checker to fight. Algorithms that need indices in Rust are strongly typed references in Goose. Generally pleasant easy to read and write code.

The biggest thing against DX may be exactly where performance comes from: you need to think a bit on where to store your data :)

groundzeros2015 6 hours ago||
> and no undefined behavior

Where is the behavior specified?

Aardappel 3 hours ago||
In the language spec: https://aardappel.github.io/goose/docs/goose_spec.html
vanderZwan 12 hours ago|||
Well, "safety" is a lot of things so you have to be a bit more specific than that about your use-cases. And I can't really answer it either way - I think WvO has to chime in about that himself - but I can point to some things that might give you some idea of what to expect. Here's what WvO wrote a few weeks ago when he shared Goose on twitter:

> Goose: my latest programming language. Safer, faster and less memory than Rust/C++ for algorithms where tightly packed, flat data structures matter.

> It can represent more kinds of data structures as flat, pointer-free bytes than any language I know.

https://xitter.cf/wvo/status/2107979660558766351

So one way to answer might be: how often do you reach for unsafe when using Rust? If you don't I guess Rust is safer. If you do… it gets trickier.

As for UB, I guess you could try looking through the spec and/or the reference? Like, the code is mostly generated by Claude after WvO wrote a specification. If it were anyone else I'd be worried, but given WvO's cv I actually suspect that means the spec leaves basically no ambiguity.

However, Goose compiles to C. Does that by definition mean UB sneaks in, or is there a "UB free" C subset? I don't write C, so I don't really know.

jibalt 2 hours ago|||
Certainly there's a UB free C subset ... everything specified by the C Standard or designated as implementation-defined is UB free by definition.

UB in C potentially destroys the universe so C programmers do their best to avoid it. A backend that generates C code is a lot more easily constrained than arbitrary manual code. While it's conceivable that a C backend could produce UB code, it would be a severe bug and isn't likely. It most certainly isn't "by definition" ... that suggests some serious conceptual error.

weinzierl 11 hours ago|||
I guess my question is if you can trigger UB in regular Goose and if you can, would it be considered a bug. I realize that this doesn't necessarily have a simple yes or no answer but I still think it'd help to know if Goose is more on the C++ side or the Rust side.

The complete omission of UB in the README could be one of two things. Either that the topic is not important or that it is considered a given and not worth mentioning.

vanderZwan 11 hours ago|||
Hmm, well the benchmarks always use an explicit "faster than idiomatic C/C++ and safe Rust". Similarly it also notes that in theory you could write equally fast C/C++ (since Goose compiles to C), but it would be an unreadable, unsafe mess.

Note also the fact that e.g. array indexing has bounds checks without escape hatches for the programmer, but the compiler can elide quite a few of them, and the language has tools to help the programmer write code that is guaranteed to be check-free.

I think that suggests the ambition is to compete with Rust in the domain of combining safety with not compromising on performance.

jibalt 2 hours ago|||
Goose has no undefined behavior.
adastra22 10 hours ago||
Goose is written by a game developer. They tend to concern themselves with C++'s niche.
hbogert 1 hour ago||
mighty interesting, i scanned the nuances about the memory model, but it doesn't explicitly say so, but am I right that some workloads will result in heavy fragmented physical memory allocations?
baud9600 5 hours ago||
Great work on Goose, a whole load of practical thought went into it!

I’d love to see 1st class lightweight ‘processes’ and typed comms, like CSP. These light processes would be cheap to spawn in the thousands, with synchronous comms. So it’s possible to quickly use arbitrary networks rather than OS thread worker pools with queues. Maybe like:

fn produce(out: chan<i32>) { for i in 1000 { send(out, i); } }

fn consume(inp: chan<i32>) { for i in 1000 { print(recv(inp)); } }

fn main() { let c = chan<i32>();

  par {
    produce(c);
    consume(c);
  }
}
Aardappel 3 hours ago|
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...
AnEro 13 hours ago||
Such a cool idea! I've been toying around making a few libraries to force languages to do that direct io zero-read mapping to data structures. Ofcourse this looks way better and infinity less hacky, but it is a fun and trippy experience to find someone working in the same direction as you independently.
malkia 8 hours ago||
How would this work in wasm land? It's a bit badly put question, because this leaves out a lot of context - wasm - where, how, what implementation, but from my simple understanding most of the wasm is 32-bit running in a browser. For this to work, it'll need true virtual 64-bit (or 48-bit) address space. The host, being the browser, or something else, may provide it, but....

If the host needs to load several of these .wasm, compiled with goose, then it'll have to run them in separate (browser) instances too (or maybe that's how wasm works by default - not sure).

It just got me thinking - the languge is prepared to translate into javascript workers, because it's really single threaded by nature with communication between threads (or put in the dart languages term "isolates"), which makes them perfect for the browser, now the only question is the memory layout.

Aardappel 3 hours ago||
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.
creata 7 hours ago||
I don't know if it's applicable here, but Wasm programs can access multiple memories.
Aardappel 3 hours ago||
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).
malkia 8 hours ago||
For Windows, these N data stacks would probably just RESERVE the address space, and as it grows COMMIT it, right?

I guess there would be some penalty to be paid here for smaller pages, but being mostly contigous might also help some.

That to be said, such language seems to require 64-bit virtual address space in order to function reasonably, right?

Also a .dll written in it might not be the best suited, for example if loaded in the middle of fragmented virtual address space it may need to find itself hard to allocate N contigious data stacks (do they absolutely have to be contiguous, what if they are simply ropes or deques or connected chunks ... obviously if some data structure requires to be contigous that would be a problem, but maybe this can be expressed somehow.... or maybe I'm overthinking here).

Super excited about this!

Aardappel 3 hours ago|
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.
kadw 12 hours ago||
It would be really great to see how it fits in embedded systems, MCUs in particular!

Embassy (https://github.com/embassy-rs/embassy) uses this concept of no heap allocation and I find it really solid. Even if you write in C, most of the times you don't use heap. MISRA, the C coding standard for automotives, doesn't allow dynamic allocation!

Aardappel 12 hours ago||
The language as it stands actually uses relatively little physical/committed memory, so could be used in embedded systems, but does rely on there being a 64-bit address space, which is probably still not as common in embedded.
malkia 9 hours ago||
I was going to ask the same, but I guess it may also not be good fit for some kernel programming, given that the heap is shared along with other code.

But sounds great for 64-bit user space, with enough (48-bit, or more) virtual addressing available. Obviously one can hit some snags if for some reason quite large allocations has to be done, but maybe one has to rethink that too.

I'm starting to fall in love with this approach ;)

wewewedxfgdf 10 hours ago|
What are the down sides? That's the key question when a better thing comes along.
Aardappel 9 hours ago|
These are some downsides: https://github.com/aardappel/goose/blob/master/docs/tutorial...
wewewedxfgdf 9 hours ago|||
I'd put the pros and cons right up front on the README.

Selling the positives for a new programming languages should go hand in hand with a realistic thorough analysis of the negatives.

Negatives of the language as a brief point 18 on the tutorial makes the negatives look hidden.

malkia 9 hours ago||
He is not "selling" anything. I don't see a price, quite the opposite - it's on the user to evaluate it's points, not on the "seller" (that he is not). Obviously if this becomes paid, or paid through support product this would be one of the first points of the table - "what are the limitations, what should we be aware of sorts".
wewewedxfgdf 7 hours ago||
Of course he's selling. Almost every word on the front page readme is a features and benefits sales pitch.

But, as all good salespeople do, they focus on the positive and leave the negative in the fine print.

Selling happens everywhere all the time without price.

spopejoy 2 hours ago|||
> No function pointers

As in nothing functional at all? Or are there anonymous functions etc?

More comments...