From 10b1abbf097b678a22cdb288d6db8ad3f7e48bca Mon Sep 17 00:00:00 2001 From: Joseph Ferano Date: Mon, 21 Sep 2026 09:32:37 +0700 Subject: [PATCH] The last enum member takes its prefix, and the alias goes TraceLogLevel carried `warning` beside `log-warning` so that sand.flan's one call kept working while the rename landed. The review found it was not inert: render.ml folds members last-wins, so a 4 read back as :warning in the break loop, the did-you-mean offered it, and every TraceLogLevel error listed it. A spelling nobody should write was the one the compiler taught. So the call is respelled and the alias is gone. Every member of every mapped enum carries its enum's prefix now, with no exception to explain. --- DISCUSS.org | 37 ++++++++++++++++++++++++++++++++++--- FIX.org | 29 ++++++++++++----------------- sand.flan | 2 +- test/test_acceptance.ml | 2 +- vendor/raylib/bindings | 6 ------ vendor/raylib/raylib.flan | 10 +--------- 6 files changed, 49 insertions(+), 37 deletions(-) diff --git a/DISCUSS.org b/DISCUSS.org index 3c4f088..4599cf3 100644 --- a/DISCUSS.org +++ b/DISCUSS.org @@ -395,8 +395,39 @@ list (surfaced same as any other diagnostic) for every site where a conversion happened that wasn't an explicit cast. Not designed, and a real philosophy question for the language, not just an implementation task. -** pos?/neg?/zero? don't exist, and need to be generic over numeric types -Nothing named pos?/neg?/zero?/sign anywhere in the prelude. Trivial to write +** CORRECTION: pos?/neg?/zero? already exist, and generics already work +I was wrong on both counts in the original entry below (kept struck-through +for the record rather than deleted). + +pos?/neg?/zero? are already in lib/prelude.ml:493-506, and they're already +generic: `(defn pos? [x $t] bool {:where (numeric? $t)} (> x 0))` — same for +neg?/zero?. My "nothing named pos?/neg?" search was wrong because my own +grep pattern used bare `pos?`/`neg?` — the `?` is an unescaped regex +quantifier there ("s is optional"), not a literal character, so the search +silently missed every hit. Should have quoted/escaped it. + +And generics DO exist and are a real, working, monomorphized feature — +Odin-style: `$t` in a defn's parameter vector binds a type variable, bare +`t` in the body/return type reads it, `{:where (pred? $t)}` after the return +type constrains it, and the checker instantiates a fresh copy per concrete +type actually used at a call site (an instantiation cache, like Odin's +gen_procs — lib/check.ml:137-162). swap/reverse/sort/min-of/max-of/ +or-else/reduce/filter/pos?/neg?/zero? in the prelude all use exactly this. + +The "generic code over the type variable %s... milestone 5" message I +quoted also looks to have been rewritten since — lib/check.ml:1069-1092 now +explicitly says "generics were milestone 5 work. They are not" and gives a +much clearer message naming the fix ("write $%s in the parameter vector to +introduce one"). Also added since: `foreign_spelling` (lib/check.ml:301-312) +maps common other-language names (integer/uint/long/double/str/etc.) to +flan's real names — though note `int` and `float` themselves specifically +are still NOT in that list, so those two still fall through to the +type-variable-not-introduced message rather than a direct "unknown type int +— Flan spells it i32". Real change happened, but not 100% coverage of what +was originally reported. + +Original (wrong) entry, kept for the record: +~~Nothing named pos?/neg?/zero?/sign anywhere in the prelude. Trivial to write per-type ((defn pos? [x i64] bool (> x 0))), but that's the problem: we want these (and inc/dec from earlier) to work across every numeric type without writing one copy per type. @@ -410,7 +441,7 @@ not written as generic Flan functions), which is the current workaround for user-defined functions like pos?/neg?/inc/dec. Two related asks logged together: (1) add pos?/neg?/zero?, (2) make milestone-5 generics real so functions like these don't need special-casing into the compiler to be -generic. +generic.~~ ** println output goes to *flan-output*, not inline in the repl Deliberate per emacs/flan-repl.el:40-44: "a value and the program's output diff --git a/FIX.org b/FIX.org index 3eff54d..ded3757 100644 --- a/FIX.org +++ b/FIX.org @@ -4721,21 +4721,16 @@ test/test_flan.ml pins one member of each of the eleven against the C name the rule reaches, read out of the real vendor/raylib/bindings, plus the claim that every mapped enum declares a prefix at all. -** sand.flan, and the alias that is standing in for it — author's to remove -sand.flan line 121 is ~(rl/set-trace-log-level :warning)~, and the file is -the author's live WIP, so this lane did not touch it. The default suite -compiles sand.flan (test_session evaluates it whole), so the rename would -have left that red. +** sand.flan, and the alias that stood in for it — removed at the merge +The lane could not edit sand.flan, whose line 121 was +~(rl/set-trace-log-level :warning)~, so it left ~warning 4~ beside +~log-warning 4~ in the TraceLogLevel defenum with a ~constant +TraceLogLevel/warning LOG_WARNING~ line to match. The review found the alias +was not inert: ~lib/render.ml~ folds members so the last-declared wins, so a +TraceLogLevel of 4 read back as ~:warning~ in the break loop, the did-you-mean +suggested it, and every TraceLogLevel error listed it among the members. -Instead TraceLogLevel carries ~warning 4~ beside ~log-warning 4~ — a defenum -allows the same value twice — with ~constant TraceLogLevel/warning -LOG_WARNING~ in ~bindings~ so the header check still reaches it. It is the -one member in the package that does not carry its enum's prefix, and it -exists only for that one call. - -To remove it, three edits together: -1. sand.flan:121 → ~(rl/set-trace-log-level :log-warning)~ -2. vendor/raylib/raylib.flan — delete ~warning 4~ from the TraceLogLevel - defenum, and the paragraph above it that explains the alias -3. vendor/raylib/bindings — delete the ~constant TraceLogLevel/warning~ line - and its comment +So it is gone, with the call respelled, at the merge: sand.flan:121 says +~:log-warning~, the ~warning 4~ member and its paragraph are out of +raylib.flan, and the ~constant~ line is out of bindings. Every member of every +mapped enum now carries its prefix, with no exception. diff --git a/sand.flan b/sand.flan index 3df4e51..60bb8ed 100644 --- a/sand.flan +++ b/sand.flan @@ -118,7 +118,7 @@ [(FileError [c] nil)])) (defn main [] () - (rl/set-trace-log-level :warning) + (rl/set-trace-log-level :log-warning) (rl/init-window screen-width screen-height "SAND") (defer (rl/close-window)) (rl/set-target-fps 120) diff --git a/test/test_acceptance.ml b/test/test_acceptance.ml index a3526e1..41326a5 100644 --- a/test/test_acceptance.ml +++ b/test/test_acceptance.ml @@ -1923,7 +1923,7 @@ let () = ptr+len. /tmp is written to, and both optimisation levels write the same bytes, so the shared name is harmless. - Trace logging stays at :warning and no read here is out of bounds, so + Trace logging stays at :log-warning and no read here is out of bounds, so a warning appearing in this output is a real failure — [run] folds stderr in. *) let raylib_image_out = diff --git a/vendor/raylib/bindings b/vendor/raylib/bindings index fa897c1..a090a0c 100644 --- a/vendor/raylib/bindings +++ b/vendor/raylib/bindings @@ -247,12 +247,6 @@ enum PixelFormat PIXELFORMAT_ pixel- # hatch: one name the prefix rule gets wrong, said once. constant Gesture/gesture-double-tap GESTURE_DOUBLETAP -# TraceLogLevel's members are `log-`, and `warning` beside `log-warning` is -# the one member that is not. It is an alias kept for sand.flan's one call, -# which this lane is not allowed to edit; both it and this line go when that -# call becomes `:log-warning`. -constant TraceLogLevel/warning LOG_WARNING - # And the second such pair, for the same kind of reason. The rule uppercases # the Flan member name, and raylib spells the two ASTC block sizes with a # lowercase `x` — PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA — where every other diff --git a/vendor/raylib/raylib.flan b/vendor/raylib/raylib.flan index ec29ff9..5d70ea1 100644 --- a/vendor/raylib/raylib.flan +++ b/vendor/raylib/raylib.flan @@ -107,17 +107,9 @@ ;; `log-` rather than `trace-`: the enum is TraceLogLevel but the C names are ;; LOG_, `trace` is itself a member, and :log-warning is what the call reads ;; as. -;; -;; `warning` beside `log-warning` is the same value twice, which a defenum -;; allows, and it is the one member in this file that does not carry its -;; enum's prefix. It is an alias for sand.flan's single -;; `(rl/set-trace-log-level :warning)` — the file this lane was told not to -;; touch — and goes, with its `constant` line in `bindings`, when that call -;; is respelled. (defenum TraceLogLevel [log-all 0 log-trace 1 log-debug 2 log-info 3 log-warning 4 - log-error 5 log-fatal 6 log-none 7 - warning 4]) + log-error 5 log-fatal 6 log-none 7]) ;; ── Window ──────────────────────────────────────────────────────────