flan/test/programs/dyn-class-slots.flan

56 lines
2.2 KiB
Plaintext

;;;; 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)