emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: using finalizers


From: LdBeth
Subject: Re: using finalizers
Date: Fri, 31 Dec 2021 10:46:20 +0800
User-agent: Wanderlust/2.15.9 (Almost Unreal) SEMI-EPG/1.14.7 (Harue) FLIM-LB/1.14.9 (Gojō) APEL-LB/10.8 EasyPG/1.0.0 Emacs/27.2 (x86_64-apple-darwin18.7.0) MULE/6.0 (HANACHIRUSATO)

>>>>> In <878rw1pvcw.fsf@logand.com> 
>>>>>   Tomas Hlavaty <tom@logand.com> wrote:
> Hi,

> I am trying to understand finalizers in Emacs Lisp but I am unable to
> triger it.

> Here is an example (with lexical-binding):

> (defun finito ()
>   (let ((x '(a b c)))
>     (letrec ((more (make-finalizer close))
>              (close (lambda ()
>                       (print "close-resource")
>                       (setq more nil))))
>       (lambda ()
>         (when more
>           (pop x))))))
> (setq foo (finito))
> (equal '(a b c nil nil) (mapcar (lambda (x) (funcall foo)) '(1 2 3 4 5)))
> (setq foo nil)
> (garbage-collect)

> After garbage collection, I would expect to see close-resource text in
> the *Messages* buffer but there is none.

You are probably taking the wrong assumption about the effect of letrec

(macroexpand '(letrec ((more (make-finalizer close))
                       (close (lambda ()
                                (setq bar t))))
                (lambda ()
                  (when more
                    (pop x)))))

==> (let (more close)
         (setq more (make-finalizer close))
         (setq close (lambda nil (setq bar t)))
         (lambda nil (when more (pop x))))

So, `close' is nil and the lambda is never set as the finalizer.

I think Common Lisp doesn't have letrec in the standard. And you are
proabaly taking the assumption that ELisp's letrec works as well as
Scheme's one. But it is not.

> What is the expected example usage of finalizers in Emacs Lisp?
> How can I verify, that my finalizer works?

(setq bar nil)
(setq foo (make-finalizer (lambda ()
                            (setq bar t))))

(setq foo nil)
(garbage-collect)

bar ; => t


-- 
LDB



reply via email to

[Prev in Thread] Current Thread [Next in Thread]