2. Raw memory and the first unsafe program
The safe form should be your default:
i32 main() { i32 value = 42; reference := &value; stdoutln(*reference); return 0;}The smallest raw equivalent needs an explicit boundary:
i32 main() { i32 value = 42; unsafe { *i32 pointer = &raw value; stdoutln(*pointer); } return 0;}Both qualified programs print exactly 42 and return zero. The first lets the
compiler track the borrow. The second asks the reviewer to prove that pointer
is non-null, aligned, points to a live i32, has compatible access, and is not
used after value dies. It is longer in proof even though it is similar in
syntax.
Run the exact checked pair from the repository:
flecha check curriculum/fixtures/unsafe-first/safe.flflecha build curriculum/fixtures/unsafe-first/safe.fl -o build/safe-firstbuild/safe-firstflecha check curriculum/fixtures/unsafe-first/unsafe.flflecha build curriculum/fixtures/unsafe-first/unsafe.fl -o build/unsafe-firstbuild/unsafe-first4242Raw new<T> also returns an allocation error and creates a cleanup obligation.
Pair every successful allocation with exactly one free, including early
returns. Prefer an owning safe structure when raw storage is not itself the API.