From 98dce374d12c387c20c9da6db9d2a2fa820cb95f Mon Sep 17 00:00:00 2001 From: Joseph Ferano Date: Thu, 17 Sep 2026 22:06:59 +0700 Subject: [PATCH] The FFI example declared a name the prelude now has web/examples/ffi.flan opened with (declare cos-f64 [x f64] f64 "cos"), which was a fine one-liner until the prelude grew cos-f64 an hour ago. @page caught it: "cos-f64 is defined twice", with the prelude line named as the other site. It is cosh now. Same shape, same answer, and the collision is worth keeping in the page rather than editing around silently -- a reader reaching for a libm function needs to know the common ones are already there and that a second declaration of a name is refused, not shadowed. The example says so in one sentence. This is the cost of filling out the prelude, and it is the whole of it: a program that declared one of the new names for itself stops compiling, with both sites named. Nothing in the corpus or in examples/ hit it; this page did. --- web/examples/ffi.flan | 9 +++++++-- web/index.html | 11 ++++++++--- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/web/examples/ffi.flan b/web/examples/ffi.flan index d34ca00..6429f95 100644 --- a/web/examples/ffi.flan +++ b/web/examples/ffi.flan @@ -1,6 +1,11 @@ ;; A plain `declare` names a C symbol in a signature Flan can already spell: ;; no aggregate crosses, so no wrapper is generated. -(declare cos-f64 [x f64] f64 "cos") +;; +;; cosh and not cos, because the prelude already declares cos-f64 and a second +;; declaration of a name is refused with both sites named. That refusal is the +;; useful half of this example: the prelude is where the common libm calls +;; live, and a `declare` is how you reach one it does not name. +(declare cosh-f64 [x f64] f64 "cosh") (defn main [] () - (print (cos-f64 0.0)) (println "")) + (print (cosh-f64 0.0)) (println "")) diff --git a/web/index.html b/web/index.html index d8d80e5..8860532 100644 --- a/web/index.html +++ b/web/index.html @@ -1418,14 +1418,19 @@ structural rule could tell them apart.

declare names a C symbol in a signature Flan can already spell. Nothing is generated; a Flan string crosses as ptr+len, exactly as it is stored.

-
(declare cos-f64 [x f64] f64 "cos")
+
(declare cosh-f64 [x f64] f64 "cosh")
 
 (defn main [] ()
-  (print (cos-f64 0.0)) (println ""))
+ (print (cosh-f64 0.0)) (println ""))
1
-

That is 1.0, printed by the same rule as before.

+

That is 1.0, printed by the same rule as before. It is cosh and not +cos because the prelude already declares +cos-f64, and a second declaration of a name is refused with both sites +named — which is the other half of what this example shows. The prelude is where the +common libm calls live; a declare is how you reach one it does not +name.

declare-c names the C library's own function in the C library's own signature, and the compiler writes the wrapper. This is what raylib's package is made