The Goose Programming Language · Goose


A memory-safe techniques language with no heap allocator, rubbish
collector, or lifetime annotations. In this repository’s benchmarks,
Goose runs quicker than C++ and Rust whereas utilizing much less reminiscence.

Tutorial · Reference · Specification · Packages · Samples · Benchmarks · Standard library

Goose has syntax acquainted to C and Rust programmers, however
there isn’t a heap. Every dynamic worth lives inline on a
information stack managed by the compiler. Growth advances a pointer, and
reminiscence is freed when its scope ends. The language’s kind and lifelong
guidelines make this reminiscence mannequin protected to make use of.

Discord Chat Twitter Follow

Why Goose

  • Faster than C++ and than protected Rust, whereas reminiscence
    protected.
    Over sixteen benchmarks Goose runs at 3.3x the velocity of
    idiomatic C++, 1.16x hand-optimized C++ and 1.12x the most effective protected Rust, on
    1.9x, 1.3x and 1.2x much less reminiscence (results). These positive factors come from Goose’s
    information layouts and reminiscence mannequin.
  • No allocator, no GC, no reference counting, no
    destructors.
    Memory is a handful of information stacks that the
    compiler assigns statically. Freeing a million-element construction is one
    retailer, nonetheless deeply it nests.
  • Growth preserves references. A reference right into a
    rising array stays legitimate for so long as the array does. You hold typed
    references the place C++ should reserve and protected Rust makes use of
    u32 indices within the corresponding benchmarks.
  • Memory protected with zero annotations. No lifetime
    syntax, no aliasing or exclusivity guidelines, no unsafe. The
    compiler infers what each reference is rooted in and rejects references
    that might outlive their homeowners.
  • Nested information stays inline. A string, an array of
    strings, a document with variable-size fields and an array of these
    data are every one contiguous block with no pointer in it. A document
    that’s 160 bytes and an allocation in C++ is 29 bytes and none in
    Goose.
  • Enums that value what they maintain. Variable-mode ADTs
    give every worth its personal variant’s dimension slightly than the most important one’s: 4x
    much less reminiscence and 2x the velocity of a Rust enum on the
    benchmark that workouts it.
  • Links narrower than pointers. A relative reference
    shops a typed, checked hyperlink as a 1, 2 or 4-byte offset. Structures
    constructed from them are place unbiased, so your information construction is
    already its file format: saving is a write, loading is a learn plus a
    verification go that rejects hostile bytes.
  • Everything is inbuilt place, assured. A price
    is constructed at its last vacation spot by any depth of calls.
    gadgets.push(parse(line)) writes the parsed document straight
    into the array, and returning a growable array by worth prices
    nothing.
  • Returns throughout a number of calls.
    return err from load returns from a perform any variety of
    frames up, statically checked, with no unwinder, no Result
    kind and no ? on each name.
  • Threads that share nothing. A employee is compiled as
    a separate program with its personal reminiscence, and flat values cross typed
    queues as a memcpy. Data races, locks, atomics and reminiscence
    orderings don’t exist within the language.
  • Generics and higher-order features with no
    overhead.
    An untyped parameter is generic. Function values are
    compile-time entities, so xs.filter() { it > 0 }
    compiles to the loop it seems like and builds its outcome straight into
    its vacation spot.
  • Plain C in, plain C out. Goose compiles to at least one C
    file, so it runs wherever a C compiler does and calls C instantly by
    extern fn. The bundled TinyCC backend compiles and runs a
    program in-process, with no construct step.

The tutorial walks by all of
this by instance, the reference covers
the entire language subject by subject, the specification has the precise guidelines, and
the benchmarks have the numbers, losses
included.

Features

This part focuses on what distinguishes Goose. The tutorial explains these options in additional
element, and the samples present them in
thirty-one full packages.

One reminiscence
mannequin: stacks, and scope exit is the free

A program has the native name stack, static information and N information stacks,
the place the compiler works out N. A knowledge stack is a big address-space
reservation with a bump pointer, and there’s no different reminiscence. At most
one resizable worth is stay per stack and it’s at all times on prime, so progress
by no means strikes something and by no means checks a capability. All of that is proved
at compile time; the runtime tracks solely the bump pointers.

spec
§4.3
) says a constructed worth is at all times inbuilt its last residence,
propagated top-down by calls. A perform returning a grow-only
array by worth writes its components straight into the caller’s variable,
or right into a discipline of the document being constructed inside one other array, so
out-parameters principally don’t seem.

summary explains the positive factors and
losses; results.md has each
measurement, and design.md explains what
the suite assessments.

What it prices you

  • You take into consideration the place information lives: who owns this, and the way lengthy does
    its scope final. Usually the reply is “the perform that builds it”, and
    that’s free; when it isn’t, it’s a reusable pool.
  • Recursive features can not hold growable information throughout a recursive
    name; scratch ends earlier than the decision, and what outlives it’s handed in as
    a pool.
  • Arrays of variable-size components iterate however don’t index (wanting
    an index of references stored beside them), a fixed-mode enum can’t be
    pointed into, and a variable-mode one can’t be overwritten. You select
    per container.
  • No escaping closures, no perform pointers, no dynamic dispatch
    past ADT tags, and whole-program compilation solely.
  • A slot handed again to a reusable pool and nonetheless named
    reads no matter its subsequent proprietor put there: a logic bug, by no means reminiscence
    corruption.

Tutorial §18 is
the complete listing.

Install a launch

Prebuilt compilers for Windows (x64), Linux (x64) and macOS (Apple
silicon and Intel) are on the releases page,
with the graphics, audio, ui and physics packages compiled in. Unpack
one anyplace and put its listing on PATH: the compiler finds the
commonplace library, TinyCC’s runtime and the packages beside itself, and
retains what it builds underneath ~/.goose
(GOOSE_HOME). The archive additionally holds these docs, the
samples and the VS Code extension.

Running a program in-process (goose file.goose) wants
nothing else on Windows. On Linux it wants the C library’s headers
(libc6-dev, or glibc-devel); on macOS, the SDK
of the Xcode command line instruments (xcode-select --install).
goose construct additionally wants a C compiler: Visual Studio 2022 or
later, or clang, on Windows; gcc or clang elsewhere. The Linux compiler
wants glibc 2.35 or later (Ubuntu 22.04, Debian 12), the macOS one macOS
13.3 or later. macOS retains a downloaded archive’s information from operating
till xattr -dr com.apple.quarantine is run on the unpacked
listing.

Build and run

You want CMake 3.27 or later, a C++20 compiler (MSVC, clang or gcc)
and Python 3 for the check and pattern runners. TinyCC, which the
in-process backend is constructed from, is a part of the tree. The graphics,
audio, ui and physics modules are packages in repositories of their very own
(goose_gfx and goose_physics;
docs/design/packages.md):
-DGOOSE_BUILTIN_LIBS=all fetches them on the pinned tags
(git, at configure time) and compiles them into the compiler, so their
packages run with nothing else put in. Without it the compiler builds
alone, and a program importing one among them has it constructed into
~/.goose the primary time, which wants git, cmake and a C
compiler.

third_party/SDL/docs/README-linux.md);
with out them the construct leaves the gfx module out and says
what to put in.

The runner scripts desire construct/Release, then
construct/RelWithDebInfo, then construct, then
construct/Debug. Pass --exe to pick a particular
compiler; use an express Debug executable when testing with compiler
assertions enabled. The compiler is construct/goose
(construct/Release/goose.exe with the Visual Studio generator),
and it finds the usual library within the supply tree it was constructed from.
On Windows 10 model 1903 and later, its embedded manifest selects a
UTF-8 course of code web page so compiler paths don’t rely on the system
locale. Earlier Windows variations retain their legacy code web page.
Generated native executables retain their very own course of settings.

Run a program straight from supply, in-process
(goose run says the identical explicitly, and
goose examine solely typechecks):

audio reference.

The check suite and the samples run on Windows, macOS and Linux:

VS Code extension
provides syntax highlighting, the compiler’s language server
(goose lsp: errors as you kind, hover, go to definition,
completion, rename, symbols) and one-key runs by the JIT:

editors has the configuration for Neovim,
Helix and Emacs.

Documentation

  • Documentation index: the map of
    every little thing under, and the basis of the documentation web site constructed from
    these information (how).
  • Tutorial: the pleasant
    introduction, by instance. Read this primary.
  • Language reference: each function,
    subject by subject, with a compiling instance for every: the entire language,
    written to be learn.
  • Language specification: the precise
    guidelines, whenever you need to know why one thing didn’t compile.
  • Samples: thirty-one full
    packages in studying order, from a tour of the language to a JSON parser,
    a threaded Mandelbrot, a file tree constructed from two swimming pools, a spinning dice
    on the GPU, hundreds of bins raining right into a heap and a to-do listing in
    home windows of widgets.
  • Standard library: fourteen modules,
    all readable Goose underneath stdlib/, together with
    gfx, graphics on SDL3’s GPU API (how
    it is built
    ), physics, inflexible physique physics on Box3D (how
    it is built
    ), and ui, fonts, text rendering and
    game HUDs
    , home windows and widgets on Nuklear, drawn by gfx (how
    it is built
    ).
  • Building programs and using
    packages
    : goose construct, libraries from git repositories
    or directories, a program’s personal C, and how you can make a bundle of your
    personal.
  • Benchmarks: the numbers, with the
    full results and the design behind them.
  • Implementation notes: how the
    compiler works, go by go, and how it is
    tested
    .

Status

Goose is new. What exists immediately is a whole-program compiler of about
thirty thousand strains of C++, the specification, the usual library,
the samples, and a check suite that CI runs on Windows, macOS and Linux
with an additional sanitizer job. Deliberately out of scope for now: strikes
for resizable values, a couple of resizable per struct, labeled
break, namespace privateness, and extra OS/library entry. Open
gadgets are tracked within the specification’s
Appendix B
.

License

Goose is licensed underneath the Apache License,
Version 2.0
.

Authors

Wouter van Oortmerssen: Language Design, Compiler
Design, Coding requirements. home web page,
twitter.

Claude Fable: Compiler implementation, Benchmarking,
Sample & Doc writing.

History & Use of AI

This repo was produced virtually totally with AI, from a human language
design. I had designed Goose a number of years in the past, and had began to
implement it, however operating a sport startup (which is constructed on one other
programming language of mine, Lobster) there was no time to
end it. Which was unhappy, as a result of I knew Goose might do issues different
languages cannot, and it ought to exist.

I had not anticipated AI to assist with this till Fable got here out. I
thought it is perhaps succesful sufficient to do a very good job. I made it
primarily clone the type and construction of my different current compiler
(Lobster), which is why when you take a look at the code, it seems slightly related
to that. My preliminary design had left a lot of issues unspecified, and much
of forwards and backwards with Fable made me determine on all of these, and it’s
now a greater language for it.

It can be an experiment in utilizing AI to implement a brand new language,
slightly than reproduce an present one.

You might surprise why I had it work in C++, if clearly I might have used
any language, like Rust, or my very own Lobster, or.. Goose itself (that will
nonetheless occur). With Fable, it was my commentary that it’s virtually
equally succesful in any language, and the sturdy guardrails of Rust or
different languages aren’t as urgent as they as soon as had been. Since the
compiler emits C, you seemingly already must have a C/C++ compiler
round, so sticking inside one ecosystem would appear to simplify
deployment and adoption. I’ve additionally built-in libtcc and who is aware of what
different C libraries sooner or later. And, like I mentioned, to have the compiler
code mimic my present Lobster compiler appeared enjoyable, at the very least I can learn
it like it’s my very own.





Source link