From 97cb77d949b31794482139f9c628cd12a864875d Mon Sep 17 00:00:00 2001 From: Joseph Ferano Date: Sun, 13 Sep 2026 12:54:42 +0700 Subject: [PATCH] Five gaps the examples hit, written down before they are forgotten --- NEXT.md | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/NEXT.md b/NEXT.md index 2225e6c..2973abd 100644 --- a/NEXT.md +++ b/NEXT.md @@ -1,3 +1,46 @@ +## To discuss: five gaps the raylib examples hit and could not close + +Found by the lane that ported `core-2d-camera`, `core-scissor-test`, `core-window-flags`, +`core-world-screen` and `core-window-should-close`. None blocked those five. All five blocked +something else, and each is a language or checker question rather than a missing binding, which is +why they are here and not in a binding list. + +1. **A `(Ptr T)` returned from C cannot be indexed.** `indexed` in `lib/check.ml` accepts `Array` + and `Slice` only, so a C function answering `int*` is readable at element 0 through `deref` and + nowhere else. `LoadRandomSequence` is the case that hit it and `core_random_sequence` is + unportable until it moves. The question is what the answer should be: a length has to come from + somewhere before a pointer can become a slice, and C does not supply one. Possibly a + `(slice-from-ptr p n)` where the caller states the length and owns being right about it. + +2. **An enum-typed `defstruct` field is refused by the layout check**, even when the representation + is identical. The message is `DISAGREES Camera3D: field projection is CameraProjection in the + defstruct and i32 (int)`. The check is comparing a Flan enum against the header's `int` and + calling that a disagreement, which it is not — an enum is an `i32`. Worked around with an + `rl/camera-projection` helper so the call site still takes a checked keyword. Related and + probably the same decision: a keyword resolves only where an enum type is expected, so + `:perspective` cannot be written into an `i32` field directly. + +3. **The header check does not reach `defconst` or `defenum`.** `generate-c`'s claim is that every + `defstruct` and every hand-written `declare-c` agrees with the header, and that claim holds. It + says nothing about constants. **A wrong flag bit or a wrong enum member is silent** — which is + exactly the class of error the header read exists to catch, and the class hardest to see by + reading. This lane added 16 `ConfigFlags` constants and four enums by hand off the header, so the + values are right today and nothing would notice if they stopped being. + +4. **raymath is `static inline`, so there is no symbol to bind.** `Clamp`, `Vector2Add`, `Remap` and + the rest exist only in the header. `declare-c` has nothing to name. rlgl's matrix stack is + unbound for a different reason. Together they make `core_2d_camera_mouse_zoom` unfaithful rather + than merely awkward, so it was skipped. The options are writing the arithmetic in Flan, which is + what the prelude would do anyway, or compiling a small C file that re-exports them as real + symbols. + +5. **Four families are still refused by the importer for want of a `defstruct`.** `FilePathList` + (a `char**`, blocks `core_drop_files`), `Model`/`Mesh`/`Ray`/`BoundingBox` (the model and + 3D-collision families), and **function-pointer parameters** (`SetTraceLogCallback`, which blocks + `core_custom_logging`, and the audio stream processors). The first three are ordinary widening — + write the `defstruct` and they import. The function-pointer one is not, and is the interesting + one: it is the callback direction of the FFI, which nothing has needed yet. + ## Queued, 2026-09-13 (second session) — everything four lanes left behind Four lanes ran in parallel worktrees and three landed; all are merged into `dev-loop` and `dune test` is green on