;;;; Typed values crossing into dyn beside a dyn operand: a u64, a dyn nil past ;;;; a fold's pair (a bare nil is refused, see test_flan), and an is-numeric $t. ;;;; With an argument, the program runs the trap that argument names instead. (defn add-dyn [x $t] dyn {:where (is-numeric $t)} (+ x (the dyn 1))) (defn add-late [x $t d dyn] dyn {:where (is-numeric $t)} (+ x 1 d)) (defn dyn-first [x $t d dyn] dyn {:where (is-numeric $t)} (* d x 2)) (defn less-late [x $t d dyn] bool {:where (is-numeric $t)} (< x 10 d)) (defn biggest [x $t d dyn] dyn {:where (is-numeric $t)} (max x d 0)) (defn low-bits [x $t d dyn] dyn {:where (is-integer $t)} (bit-and x 7 d)) (defn boxed [x $t] dyn {:where (is-numeric $t)} (the dyn x)) (defn main [args [str]] i32 (let [z (the dyn 0) n (the dyn 4) small (the u64 9223372036854775807) big (the u64 18446744073709551615) nothing (the dyn nil)] ;; A u64 up to the largest i64 crosses as its value. (println (+ z small) (max small 0 z) (the dyn small) (= small (+ z small))) ;; A $t at i32, f64 and u64, beside a dyn in any position. (println (add-dyn 2) (add-dyn 2.5) (add-dyn (the u64 7))) (println (add-late 2 n) (add-late 2.5 n) (dyn-first 3 n) (dyn-first 1.5 n)) (println (less-late 1 n) (less-late 1 (the dyn 20)) (less-late 0.5 (the dyn 10.5))) (println (biggest 3 n) (biggest -2.5 (the dyn -1)) (low-bits 13 n) (low-bits (the u8 255) n)) (println (boxed 7) (boxed 0.25) (boxed small)) ;; A nil past the pair is compared, not refused. (println (= 1 1 nothing) (!= 1 2 nothing) (= 1 1 (the dyn nil))) (when (> (length args) 1) (let [a (at args 1)] (when (= a "u64") (println (+ z big))) (when (= a "u64-max") (println (max big 0 z))) (when (= a "u64-generic") (println (boxed big))) (when (= a "nil-first") (println (+ (the dyn nil) 1 2))) (when (= a "nil-last") (println (+ 1 2 (the dyn nil)))) (when (= a "nil-less") (println (< 1 2 (the dyn nil)))) (when (= a "nil-min") (println (min 1 2 nothing))) (when (= a "nil-bits") (println (bit-or 1 2 nothing))) ;; At a typed want too: the dyn nil traps in any position. (let [r (the i32 0)] (when (= a "nil-want-first") (set r (+ (the dyn nil) 1 2))) (when (= a "nil-want-last") (set r (+ 1 2 (the dyn nil)))) (set r (+ r (at-i32 a))) (the-literal a) (println r))))) 0) ;; A dyn beside typed operands at an i32 want: the whole form is dyn, and only ;; its answer is opened at i32, so every position wraps nowhere and traps alike. (defn at-i32 [a str] i32 (let [big (the dyn 2147483647) none (the dyn nil)] (cond (= a "big-first") (+ big 1 1) (= a "big-mid") (+ 1 big 1) (= a "big-last") (+ 1 1 big) (= a "big-pair") (+ 1 big) (= a "big-shift") (<< big 1) (= a "i32-nil-first") (+ none 1 1) (= a "i32-nil-mid") (+ 1 none 1) (= a "i32-nil-last") (+ 1 1 none) :else 0))) ;; (the dyn ) is a dyn like any other: beside nil it traps at run ;; time, as a dyn bound to a name does. And opening one at f64 or bool names ;; its site. (defn the-literal [a str] () (let [x (the f64 0.0) b false] (when (= a "lit-int") (println (+ (the dyn 1) nil))) (when (= a "lit-float") (println (+ (the dyn 1.5) nil))) (when (= a "lit-bool") (println (+ (the dyn true) nil))) (when (= a "lit-let") (let [d (the dyn 1)] (println (+ d nil)))) (when (= a "want-f64") (set x (the dyn 3)) (println x)) (when (= a "want-bool") (set b (the dyn 3)) (println b))))