- Manual memory management; no garbage collector (which also means it is not as memory safe as Go)
- No hidden memory allocations
- No hidden control flow (no panic/recover)
- Syntax closer to the C/C++ family (statements terminated by semicolons, if/while expressions between parenthesis)
- "comptime" for metaprogramming instead of generics
- Compile time reflection but no runtime reflection
- Can use C libraries directly without any FFI
- Can be used as a drop-in C/C++ cross-compiler with no other dependency
- Best-in-class performance using LLVM as a backend
- Support no standard library for bare metal or embedded
- Concurrency with async functions (instead of goroutines and channels)
- A very interesting error handling mechanism using error values, try, catch, errdefer and error return traces
- Optional types (no null references/pointers)
- Declare public symbols using the pub keyword instead of TitleCase identifiers
- Test declarations are part of the language and can live in the same file as the code tested
- Integer overflow checked by default (program panics)
- Tagged unions
- Identifier shadowing not allowed
- Switch must handle all possible values
- if/for/while/switch can be used as expressions
- Operations on vectors (+, -, *, etc.), optimized using SIMD if possible (I'm under the impression that's the main reason why people want operator overloading in Go)
- Maps implemented in the standard library instead of being a built-in type
- No variadic arguments (...) to functions (use anonymous tuples instead)
- No string type (they are just arrays or slices of bytes, possibly zero terminated)
- No interfaces
- No closures
Similar to Go:
- Simplicity is emphasized
- Produces statically compiled and linked executables with no runtime dependencies
- Can cross-compile
- No operator overloading
- defer statement
I’m not qualified to contrast it with C, but I think it has fewer footguns, a build system, and probably a better standard library. The tooling is great (similar to Go).