In TXR Lisp, RAII is supported thusly:
This is GC finalization of a struct:
This is the TXR Lisp interactive listener of TXR 172.
Use the :quit command or type Ctrl-D on empty line to exit.
1> (defstruct animal nil
(:fini (me) (put-line `@me says good-bye`)))
#<struct-type animal>
2> (progn (new animal) nil) ;; make animal without referencing from REPL
nil
3> (+ 2 2)
4
4> (sys:gc)
#S(animal) says good-bye
t
OK, now with-objects macro: 5> (with-objects ((a (new animal)))
(prinl a))
#S(animal)
#S(animal) says good-bye
#S(animal)
with-objects invokes finalizers explicitly, before objects become unreachable.Also, what if a constructor throws? Let's derive animal to dog which bails at `new` time:
6> (defstruct dog animal
(:fini (me) (put-line `@me: woof woof`))
(:postinit (me) (error "refuse to construct")))
#<struct-type dog>
7> (new dog)
#S(dog): woof woof
#S(dog) says good-bye
** refuse to construct
** during evaluation at expr-6:3 of form (error "refuse to construct")
The object instantiation logic catches exceptions and invokes finalizers on a partially constructed object (in the proper order as you can see: derived, then base).