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.
This commit is contained in:
Joseph Ferano 2026-09-17 22:06:59 +07:00
parent 901376ba49
commit 98dce374d1
2 changed files with 15 additions and 5 deletions

View File

@ -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 ""))

View File

@ -1418,14 +1418,19 @@ structural rule could tell them apart.</p>
<p><code>declare</code> 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.</p>
<pre><code>(declare cos-f64 [x f64] f64 "cos")
<pre><code>(declare cosh-f64 [x f64] f64 "cosh")
(defn main [] ()
(print (cos-f64 0.0)) (println ""))</code></pre>
(print (cosh-f64 0.0)) (println ""))</code></pre>
<pre><code class="sh">1</code></pre>
<p>That is 1.0, printed by the same rule as before.</p>
<p>That is 1.0, printed by the same rule as before. It is <code>cosh</code> and not
<code>cos</code> because <a href="#prelude">the prelude</a> already declares
<code>cos-f64</code>, 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 <code>declare</code> is how you reach one it does not
name.</p>
<p><code>declare-c</code> 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