aboutsummaryrefslogtreecommitdiff
path: root/README.md
diff options
context:
space:
mode:
authorGravatar zinc <zinc@downsta.ir> 2026-10-14 09:33:03 +0000
committerGravatar zinc <zinc@downsta.ir> 2026-10-14 09:33:03 +0000
commitebaa15f02dd0e5aa358ea2e527ae4557e40b4e9c (patch)
tree9f53ccfed1eedd90df2747bdfd0e9ea907caee95 /README.md
parenttodo: record the reverted unchecked trial and what it showed (diff)
constants inside structs, and typo suggestions for fields and static members
const NAME = e; inside a struct body declares a compile-time constant named Struct.NAME, reached as Struct.NAME or by bare name in the struct's methods. A misspelled field or Struct.name member now ends its error with '; did you mean 'name'?' on the member word, which the language server turns into a quick fix.
Diffstat (limited to 'README.md')
-rw-r--r--README.md2
1 files changed, 2 insertions, 0 deletions
diff --git a/README.md b/README.md
index 235fedb..ef1ddf8 100644
--- a/README.md
+++ b/README.md
@@ -311,6 +311,8 @@ p.dist(q);
underneath, a method is an ordinary function called `point.dist` whose first parameter is `point* this`, compiled once the struct is complete, so a method can call the ones declared after it. a field with the same name wins over a method. a method of a generic struct is a generic function over the struct's parameters, compiled for each set of arguments it is called with (the receiver says which), so `this.items[i]` and `sizeof(K)` inside it are exact.
+a `static` function (`static fn name(...)` or `static int name(...)`) has no `this` and is called as `Struct.name(args)`, or `std.Text.itoa(n, buf)` for a library group. a struct can also hold untyped constants: `struct Text { const MAX = 24, MIN = 1; int len; }` (a type before the name, as in `const int MAX = 24;`, is read and dropped). the initializers are constant expressions, a constant takes no space in the struct, it is reached as `Text.MAX` (`std.Text.MAX` from a library), and a method or static function of the struct can use the bare name `MAX`. a misspelled field, static function or constant gets the same `; did you mean 'name'?` suggestion as an undefined function, and the language server offers it as a quick fix.
+
`fn(a, b) { ... }` in an expression is a closure. the value is a heap block: word 0 is the body's entry, and its captured cell pointers start at word 3. the vm only runs code in the code area, so the block is never executed. a call through a value checks whether the callee is at or above `HEAP_LO`. a plain function is called as it is. a closure is called with the block plus 3 as its environment and jumps to the entry in word 0. captured locals and parameters share cells with the enclosing function and sibling closures, so mutations stay visible after the closure is made and after its creator returns. captured owned objects remain alive with those cells. the block is an owned object; a fresh closure can be passed directly to a proved borrower, and returning one transfers it to the caller. `examples/learn/25-closures.zc` and `examples/learn/26-closure-state.zc` cover these.
`fn:type(args)` declares a closure's result and parameter types. an owned closure can be returned from a factory with `.u`; its captured cells remain alive for the returned value. [the typed closure example](examples/learn/30-typed-closure.zc) covers this form.