The script is in tools/ rather than thrown away, because two lanes are
writing Flan in the old spelling right now and their files need the same
pass at merge.
It works on forms, not on text: a keyword becomes a dot only where it sits
in a field-label position inside a brace, so an enum member in value
position, a map key inside an EDN string and a type-position {K V} are all
left alone. :keys keeps its colon -- it names no field.
46 lines
1.7 KiB
Plaintext
46 lines
1.7 KiB
Plaintext
;;;; handler-bind and signal — spec-conditions.md §1 and §2.
|
|
;;;;
|
|
;;;; The accumulation case, which is what makes these two worth having on their
|
|
;;;; own: signal returns Unit, a handler that returns normally leaves the
|
|
;;;; signalling function to carry on, and with nothing matching signal is a
|
|
;;;; no-op. No control flow is altered, so none of the transfer machinery
|
|
;;;; restart-case needs exists yet.
|
|
(defstruct AssetMissing [id i32])
|
|
(defstruct Corrupt [id i32])
|
|
|
|
(defvar seen i64)
|
|
(defvar other i64)
|
|
|
|
;;; Signals twice and keeps going both times — that is the whole of §1.
|
|
(defn load-all []
|
|
(signal (AssetMissing {.id 1}))
|
|
(signal (AssetMissing {.id 2}))
|
|
(signal (Corrupt {.id 3})))
|
|
|
|
(defn main [] i32
|
|
;; No handler: a no-op, not an abort and not a message (§2).
|
|
(load-all)
|
|
(print seen) (println "") ; 0
|
|
|
|
(handler-bind [(AssetMissing [c] (set seen (+ seen (i64 (.id c)))))]
|
|
(load-all))
|
|
(print seen) (println "") ; 1 + 2 = 3
|
|
|
|
;; Two clauses, and only the matching one runs for each condition.
|
|
(handler-bind [(AssetMissing [c] (set seen (+ seen 10)))
|
|
(Corrupt [c] (set other (+ other (i64 (.id c)))))]
|
|
(load-all))
|
|
(print seen) (println "") ; 3 + 20 = 23
|
|
(print other) (println "") ; 3
|
|
|
|
;; Nesting: the inner frame does not displace the outer one, so both run.
|
|
(handler-bind [(Corrupt [c] (set other (+ other 100)))]
|
|
(handler-bind [(Corrupt [c] (set other (+ other 1000)))]
|
|
(signal (Corrupt {.id 0}))))
|
|
(print other) (println "") ; 3 + 1000 + 100 = 1103
|
|
|
|
;; And the stack is back to what it was: no handler, no effect.
|
|
(load-all)
|
|
(print other) (println "") ; 1103
|
|
0)
|