;;;; Typed class slots, and set on a slot. ;;;; ;;;; A slot vector reads as a defn's parameter vector: [pause bool] is a slot ;;;; of type bool, and a name followed by another name is a slot with no type, ;;;; which holds any dyn value. The type is checked when a value is stored -- ;;;; by the constructor, by put and by set -- and not when one is read: an ;;;; instance is a dyn map whatever its slots say. ;;;; ;;;; set writes a declared slot. A class declares its slots, so one always ;;;; exists and (get s :pause) is a place, where a plain map's absent key is ;;;; not. dyn-slot-trap.flan has the refusals. (defclass state [pause bool step i32 speed f64 name str tag]) ;; A class is a slot type, and (Option T) admits nil beside a T. (defclass node [owner state next (Option node) weight (Option f32)]) (defn twelve [] i64 12) (defn main [] i32 (let [s (state false 3 1.5 "sand" :x)] (println s) (set (get s :pause) true) (println (get s :pause)) ;; An i32 slot takes any int in i32's range; a dyn caller passes the ;; value as it is, with nothing converted first. (set (get s :step) -7) (println (get s :step)) (set (get s :tag) [1 2]) (println (get s :tag)) ;; put reaches the same check for a declared slot, and still inserts a ;; key the class does not declare -- an instance is an open map to put. (put s :speed 2.5) (put s :scratch 9) (println (get s :speed)) (println (get s :scratch)) (println (length s)) ;; A typed caller boxes into the dyn parameter as any call does. (set (get s :step) (twelve)) (println (get s :step)) ;; An int into a float slot widens, as it does into a typed f64 ;; parameter, when the float holds it exactly. (put s :speed 3) (println (+ (get s :speed) 0.5)) ;; Exact is a round trip, not a range: 2^54 is an f64 exactly. (put s :speed 18014398509481984) (println (= (get s :speed) 18014398509481984.0)) (let [n (node s nil nil)] (set (get n :next) (node s nil 2)) (println (get (get n :next) :weight)) (set (get n :weight) nil) ;; 2^30 is an f32 exactly, though it is past f32's 24-bit significand. (set (get n :weight) 1073741824) (println (class-of (get n :owner))))) 0)