cheatah ↔ C++
🐱 It's C++ underneath — so a lot of C++ is just cheatah. 🐆
cheatah transpiles to modern C++ and every value is a C++ value (int → long long, str → std::string, list/dict → std::vector/std::unordered_map). So a surprising amount of C++ is available first-class, in ordinary cheatah syntax — no cpp { … } escape hatch, and none of the escape hatch's loss of memory safety. This page is the map of what you get natively, and where the escape hatch is still the door.
First-class — native cheatah, lowers straight to C++
C++ construct | In cheatah | Lowers to |
|---|---|---|
|
| a C++ |
Methods on a record |
| a member function |
Aggregate construction |
| a C++20 designated initializer (omitted fields zero-init) |
|
| a scoped, printable |
Concepts (interfaces) |
| a C++20 concept + a |
|
|
|
Value semantics + RAII |
|
|
Generics |
| template instantiations, concept-constrained |
Operators |
| the matching C++ operators ( |
Slicing / indexing |
| bounds-checked element/subrange access |
The whole standard library |
| linking real C++ modules and calling them with method syntax |
Because all of the above lowers to value types, smart pointers, and RAII, it stays memory-safe — the compiler emits no raw new/delete for any of it (see Security).
Deliberately different from C++
No raw pointers, references, or manual memory in the surface language — ownership is value-and-scope. The owning guards (
io.File,socket.Conn,tls.Conn,websocket.Client) replace hand-managed handles;withgives deterministic cleanup.No inheritance. "is-a" is expressed with interfaces (concepts), not base classes — records only implement contracts; they never derive.
Exceptions carry a KIND, not a type —
except e of "index" { … }selects on a string kind rather thancatch (const T&), because there is no inheritance to build an exception hierarchy from.eis anErrorwith.kind()and.message(), and prints and compares as its message.raise "msg"raises kind"error";raise Error("kind", "msg")names one; a bareraisein a handler re-raises. Handlers run in order,finallyruns on every exit path, and anything no handler claims keeps travelling rather than being swallowed.//is floor division and**is power (not C++'s comment / no-power);^is bitwise-xor as in C.
Still the escape hatch:
For genuine C++ that has no cheatah surface, drop into a raw block — file scope for #includes/helpers/types, inline inside a function where it can read and write cheatah locals:
import io
cpp { static long long triple(long long n) { return n * 3; } } # file scope
fn demo() {
let acc = 0
cpp { for (int i = 1; i <= 4; ++i) { acc += i; } } # inline — sees `acc`
return acc + triple(2)
}
io.print(demo()) # 16Reach for it for: raw pointers / manual allocation, arbitrary third-party C++ headers and libraries, lambdas, templates you write by hand, and any other C++ feature not listed above. (Threads no longer need the escape hatch — import thread spawns cheatah fns natively; see the threading contract.) Memory safety is not guaranteed inside cpp { … } — a raw block bypasses the value-semantics guarantees, so lifetimes and undefined behavior are your responsibility, exactly as in C++. Keep it small and rare; everything around it stays native and safe.
