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>
9 lines
666 B
Markdown
9 lines
666 B
Markdown
bump: minor
|
|
type: feat
|
|
**Functions are values (L2).** `fn(int, float) -> bool` is a type, `fn name` is any top-level
|
|
function's value (it used to be only a thread worker's address), 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 different function types do not mix, a call through one checks its argument
|
|
count, and a value may be `null`. A registry can hold behaviour and a package can take
|
|
callbacks. `Job.parallel_for` still checks that its worker takes (int, pointer) and returns
|
|
nothing. `ludic-dev selfhost-build` now says why it failed instead of exiting 1 silently.
|