flan/test/programs/dyn-basic.flan
Joseph Ferano c8091bdbf9 One unannotated add, answering 5 to the integers and 3.75 to the floats
The boundary and the operators, which are the two halves of dyn being a type
rather than a word the checker tolerates.

Typed to dyn is implicit and dyn to typed is not, and the asymmetry is the
design: boxing loses nothing and can happen wherever a dyn is wanted, while
unboxing can fail at run time on a value the compiler cannot inspect, so it
happens only where somebody wrote a type. Both go through expect, because
expect is already the one place a wanted type meets a produced one, and every
annotating site already calls it.

Literals take their width from the dyn, not from the default. (defvar x dyn 5)
holds an i64 five: the ABI carries one integer width, so the defaulting question
never arises, and the literal is built at i64 rather than boxed after defaulting
to i32 -- which also means 3000000000 is a dyn integer.

An operator with one dyn operand is the runtime's. binary has already checked
the second operand against the first, so a mixed pair arrives with the typed
side boxed and the fold only has to call flan_dyn_add instead of adding. The
comparisons answer bool and not a dyn holding one, because a comparison is
almost always the test of an if; a program that wants it as a value boxes it
again for free at that boundary. = and != never trap -- two values of unrelated
types are unequal, not an error -- and the orderings do.

Types.equal had no Dyn case, so dyn was equal to nothing including itself.

print hands the whole value to the runtime rather than walking it: every other
arm of the structural printer exists because a Flan value carries no header and
only the compiler knows what it is, and a dyn is the exact reverse.

The compiler carries the dyn runtime the way it already carries flan_rt.c, with
the header pasted in front of the stub so there is one self-contained
translation unit and one contract.
2026-09-19 05:55:48 +07:00

16 lines
576 B
Plaintext

;;;; An unannotated defn, called at two different types.
;;;;
;;;; [(defn add [x y] dyn (+ x y))] states no type for either parameter, so both
;;;; are dyn, and the + in the body is the dyn one: a call into the runtime that
;;;; decides on what the two words actually hold. The same function serves the
;;;; integer call and the float call, which is the whole of what the feature
;;;; buys and is not something the typed language could express at all.
(defn add [x y] dyn (+ x y))
(defn main [] ()
(print (add 2 3))
(print "\n")
(print (add 1.5 2.25))
(print "\n"))