flan/test/programs/break.flan
Joseph Ferano 9a820d86cd Sweep every field label from the colon spelling to the dot
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.
2026-09-12 14:47:54 +07:00

35 lines
1.2 KiB
Plaintext

;;;; The dev-build break loop — spec-conditions.md §2.
;;;;
;;;; An unhandled error used to kill the program. Here it stops instead, on the
;;;; frame that erred with nothing unwound, and waits for someone to pick a
;;;; restart. Two of them, and the run takes a different one each time, so a
;;;; break loop that always resumed the same way could not pass.
(import agent "vendor:agent")
(defstruct Missing [id i32])
(defn fetch [n i32] i32
(restart-case
(do (error (Missing {.id n})) 0)
(use-placeholder [] -1)
(retry [] 7)))
;;; Two frames offering the same name, which §4 says resolves to the inner one
;;; and only ever the inner one. The outer clause is therefore on every list a
;;; break loop prints and reachable from no name at all, which is why a restart
;;; is taken by *index* now. 900 is the proof: it is the only value in this
;;; file that by-name lookup cannot produce.
(defn shadowed [n i32] i32
(restart-case
(+ (restart-case (do (error (Missing {.id n})) 0)
(retry [] 5))
100)
(retry [] 900)))
(defn main [] i32
(agent/start "/tmp/flan-break.sock")
(print (fetch 1)) (println "")
(print (fetch 2)) (println "")
(print (shadowed 3)) (println "")
0)