feat(lang): functions are values (L2), and render3d takes its scene as callbacks
fn(int, float) -> bool is a type, fn name is any top-level function's value, and a call through a local, a global, a record field, a slice element, a parameter or a result of a function type is an indirect call; two function types mix only when equal, a call checks its argument count, and a value may be null (examples/functions/values.ludic). Job.parallel_for keeps its worker check. render3d's scene is registered rather than required by name: r3d_on_draw, r3d_on_casters and r3d_on_stream_fill (hooks.ludic). The two rendering examples register theirs - and had defined scene_draw_casters with no parameter while the renderer passed one, which nothing checked. render3d declares numbers float itself; smooth.ludic is converted to floats and returns when r3d_init fails instead of running on into a segfault. Noise.* check their argument count (a call one short crashed the compiler). selfhost-build says why it failed. The migration tool reads a declared float as evidence. Seed regenerated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
dc75a5a5ab
commit
0c73287e35
23 changed files with 71430 additions and 68575 deletions
31
examples/functions/values.ludic
Normal file
31
examples/functions/values.ludic
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
# values.ludic — L2: a function is a value. `fn(int) -> int` is a type; `fn name` is any
|
||||
# top-level function's value; a call through a local, a global, a field or an element of a
|
||||
# function type is an indirect call. A registry can hold behaviour, and a package can take one.
|
||||
#
|
||||
# Running it prints: 42 10 25 49 81 1.5 1
|
||||
program FunctionValues {
|
||||
numbers float
|
||||
property Kind { name: string = "", use: fn(int) -> int = null }
|
||||
function double(x: int) -> int { return x * 2 }
|
||||
function square(x: int) -> int { return x * x }
|
||||
function half(x: float) -> float { return x / 2.0 }
|
||||
var op: fn(int) -> int = null
|
||||
function run_with(f: fn(int) -> int, v: int) -> int { return f(v) }
|
||||
function pass_on(f: fn(float) -> float) -> fn(float) -> float { return f }
|
||||
entry {
|
||||
op = fn double
|
||||
print(op(21))
|
||||
let ops = new []fn(int) -> int
|
||||
push(ops, fn double)
|
||||
push(ops, fn square)
|
||||
for i in 0 .. len(ops) { print(ops[i](5)) }
|
||||
let k = new Kind
|
||||
k.name = "square"
|
||||
k.use = fn square
|
||||
print(k.use(7))
|
||||
print(run_with(fn square, 9))
|
||||
let h = pass_on(fn half)
|
||||
print(h(3.0))
|
||||
if op != null { print(1) }
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue