PORTING.md Tier 1 item 6, the last one on that list. Not a language feature and nothing was added to the language: restart-case, struct assignment and fixed-arrays-as-values were already built, and what was missing was the worked example. test/programs/frame-rollback.flan is it — snapshot at the top of the frame, restore in the `continue` clause, over one fixed array and one struct, which is engine.clj's grids plus engine.lisp's shallow copy of the state object. Two `set`s each way, because both are values; there is no IntGrid walk and no sb-mop:class-slots walk to write. The decision in it is the ordering against defers, and both orderings compile. An answered bounds failure runs the abandoned function's defers, innermost-first, before the restart clause body starts. Restore in the clause is therefore the last write on the abandoned path and needs no agreement with what any defer did on the way out. The rejected alternative — restore in a defer inside the frame function — also runs on the ordinary return path, so it rolls back the frames that succeeded, and nothing reports that as an error. Pinned with numbers rather than prose: a tick counter inside the snapshot, written by the frame's defer, reads its pre-frame value, while a counter outside the snapshot shows the defer ran. And there is a negative control, the same bad frame with a `continue` that only counts, because "state equals snapshot" passes trivially on a program that never wrote anything. Three acceptance rows beside bounds-condition.flan's, for the same reasons: -O0, and the dev build where every call goes through a cell.
Description
Languages
OCaml
67.2%
Emacs Lisp
15.2%
C
10.4%
HTML
2.9%
Standard ML
2.8%
Other
1.5%