The Goose Programming Language
361 points - yesterday at 7:06 PM
SourceComments
For instance, how would you represent a hash table where the values are strings and at random, the program inserts or deletes a random string?
This doesn't seem like something you could easily represent. The only way I can think of is to keep a stack that holds all of your strings, and you periodically compact it.
Edit: Maybe you could also have a separate stack for strings of various sizes. One each for strings less than 8, 16, ... bytes. But at that point you're basically implementing your own malloc by hand.
Edit: Fwiw I do think Goose is very cool! I've had to hand-roll a lot of similar stuff in Rust before to speed up memory management
That reminds me of Dart Isolates - https://dart.dev/language/isolates
From what little I read in the literature I seem to recall that there were enough programs with quite a bit more memory usage that they decided this approach was a dead end.
Does anyone know anymore details?
Still, for a large number of programs - like data-oriented applications - it’s probably a good fit. It might work ok with entity-component game systems as long as you reuse old memory…
I wonder if the name of the language was inspired by the way geese fly in formation, with trailing birds saving energy by flying inside the aerodynamic shadow of the leaders, and swapping in and out as needed. If so, a very nice metaphor for the memory management model.
I was also impressed by the documentation. As we know AI-generted docs tends to be rather mediocre, but the author has clearly invested time in making in readable such that the relevance and rationale of design decisions provide the context that a curious programmer needs to understand why things are implemented in a particular way.
I really appreciated the detailed samples, ranging from simple algorithmic theorems up to a small game. Again, I don't have the experience to rate the language vs others, but I was struck by readable the code was and how easy it was to follow task flow. Not having to think about classes is always a plus!
Anyway, I usually the the offering of a new language with dispassionate interest, as something to be aware of and but not get too invested in or familiar with until it gains enough popularity to have a good shot at longevity. Goose is the first language in a long time where I looked at it and immediately thought that I'd like to use it for its own sake.
The relative references and built in binary structure validation also enable direct memory mapping of data structures and immediate use of network data. "Parsing" file and network data is often 100x slower than it needs to be." - John Carmack
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.
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);
}
}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.
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!
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!
I doubt this can work well in all cases. Sooner or later one needs proper heap.
There might be some decent design ideas there but if you can't be arsed to write them down in your own words but instead make me read AI generated slop I am out.
What are the ergonomics of this I wonder.
And doc is the slop.
Yet, the author expects YOU to read all of what they didn't write. So I ain't reading all of that.
If anyone is interested, I'm fairly close to finalizing Slang and I'm considering open-sourcing it in the near future. What originally started as a simple register based lang for an embeddable VM turned into an insanely expressive meta?programming language. Full system Fω, expansive whole program reflection (you can reflect on absolutely anything), string memory & logic safety..
You can do stuff like this:
(fn answer () -> i64 0)
(defpass build-answer
(phase source)
(transform (lambda (f)
(fn-with f 'body '(let ((a (arr (42)))) (at a 0)))))
(safety (lambda (goal) (syntax (refl)))))
(run-pass build-answer answer)
(fnmut answer
(transform (lambda (f)
(if (memory-safe? (check-memory (current-program)))
f (syntax-error 'unproved-memory)))))
(defpass inspect-ssa
(phase ssa)
(transform (lambda (f)
(if (memory-safe? (check-memory (ssa-current-program)))
f (syntax-error 'unproved-ssa-memory))))
(proof (lambda (goal) (syntax (refl)))))
(run-pass inspect-ssa answer)
(answer)
or this: (fn next ((i i64)) -> i64 (+ i 1))
(fncontract next
(ensures result (successor (Eq i64 result (+ (old i) 1)) auto)))
(fn read-second ((i i64)) -> i64
(let ((a (arr (0 42)))) (at a i)))
(fncontract read-second (requires (one (Eq i64 i 1))))
(let ((i (next 0)))
(with-proof ((one (Eq i64 i 1) (result-proof i successor)))
(print (read-second i))))
it also supports full inline asm or llvm ir: (var answer 0)
(asm (input rdi 20)
(input rsi 22)
(output rax answer)
(mov rdi rax)
(add rsi rax))
(print answer)
(macroop \ (a) (asm (mov a rax)))
(\ 42)
(print (llvm add 20 22))
(print (->i64 (llvm fused-multiply-add (f64) 6.0 7.0 0.0)))
(llvm fn sum32 ((x i32) (y i32)) -> i32
(block entry
(value answer (llvm add x y (declare (flags nsw))))
(llvm return answer)))
(print (->i64 (sum32 (the i32 20) (the i32 22))))
Even though you can write this by hand, the core idea is to get a very dense and terse language that LLMs can emit while guaranteeing safety and performance.Edit Man, two posting about Goose back to back. Carmack alone might be enough to read further.
Please share it with logistics guys, since putting stuff from here and there into warehouse storage, then taking away, put some more in than planned sometimes, keeps spinning their heads. They need all the good logic!
So, yet another programming language, that's nice. I never thought there will be one more beyond English.
Evolution of programming languages:
- 1940s → Machine Code ( 0s 1s )
- 1949 → Assembly
- 1957 → FORTRAN
- 1959 → COBOL
- 1964 → BASIC
- 1970 → Pascal
- 1972 → C
- 1983 → C++
- 1991 → Python
- 1993 → Ruby
- 1995 → Java
- 1995 → JavaScript
- 1995 → PHP
- 2000 → C#
- 2009 → Go
- 2010 → Rust
- 2011 → Kotlin
- 2011 → Elixir
- 2012 → TypeScript
- 2014 → Swift
- 2015 → Solidity
- 2026 → English