as-slice was a warning, not an operation. The input type already decides which of the two things happens — a Vec can only be borrowed, an array or a string can only be viewed, and no call site picks between them — so the second name expressed no choice a reader could make. And it warned at the moment the view is taken, which is the one moment nothing is wrong; the danger arrives later, at the push. slice now takes a Vec at all three arities and as-slice is gone. (slice v lo) was free, and is the arity the Vec never had: the runtime already reads a hi of -1 as "to the end", so the tail form passes the caller's lo and the same -1 — no slot, no length read, no second evaluation. The merge is entirely in the checker; the Vec path builds the flan_vec_as_slice call it always built and neither backend has a line about any of it. A Vec a call returned is refused at every arity, and not for the array's reason. (slice (mk)) over an array dangles. (slice (make-vec)) does not — the storage outlives the expression — but the header is a temporary, so nothing can ever free the block. The refusal says that and names the let. The name's own refusal sits in ordinary_call after every table, so a program that defines an as-slice still reaches its own. It reads for somebody who has never heard of the old name and writes the call back out, spelling each argument that is a name or a number. The warning moved to where it bites: BUILT.md gains a section beside the Vec table and the push row points at it, spec-memory.md's Borrowing says the same. Investigated and deliberately not built — a diagnostic for a live view at the push. (reserve v 100) then a slice, a push and a read is correct code under the contract the spec chose, so any flag on it is a false positive by the language's own semantics rather than by an approximation. FIX.org has the finding and the syntactic sketch that does not work.
2.0 KiB
2.0 KiB
Overview — superseded
This was the first brainstorm. It is kept for history and is no longer accurate. Read instead:
../plan.org— the design, the build sequence, and the open decisions../spec-memory.md— ownership, containers, places, generics, function values../spec-conditions.md— conditions and restarts, operational semantics../sand.flan— the first acceptance program../syntax-sketch.flan— the syntax, annotated with the decisions above
What changed since
| This document said | Now |
|---|---|
| "C-like with Roc syntax" | S-expressions, Clojure's brackets; C's value model |
| "Start with interpreter, output C later" | Frontend → typed IR → LLVM IR as text → clang. An interpreter is acceptable for milestone 2 only |
| "lists, slice, fixed-length array, matrices" | Four container types, distinct ownership: [n T], [T], (Vec T), (Map K V) — see spec-memory.md |
arr[4], arr[1..] index syntax |
(at a i), (slice a lo hi) — no infix, no bracket indexing |
const by default? |
Locals are assignable places; parameters are not; const qualifies slices and pointers |
Rust-style iterator chains ending in .collect() |
->> threading over slices; every collecting operation allocates from an explicit allocator, usually the frame arena |
Ptr a |
Kept, as (Ptr a). Cross-references use (Handle a) instead |
| option/result in the stdlib | Kept, and layered with conditions — see plan.org "Error handling, layered" |
Original text
Concepts:
- Primitives
- u8, i32, f32, bool, char
- lists, slice, fixed-length array builtin, matrices
- Control flow
- for, while, break
- Structs & tuples
- Let bindings
- `Ptr a`
- Pattern matching
- ADTs
- Mutability
- const by default?
- Functions
- Array syntax
- ranges `arr[1..]`, `arr[..3]`
- index `arr[4]`
- Stdlib
- string
- vec/dynarray
- hashtable
- option/result
C-like with Roc syntax.
Start with interpreter. Output C later down the track