help-gnu-emacs
[Top][All Lists]
Advanced

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

Unreferenced symbols in closures, and a problem with closures in minor m


From: Kelly Dean
Subject: Unreferenced symbols in closures, and a problem with closures in minor modes
Date: Tue, 28 May 2013 15:35:58 -0700 (PDT)

(setq lexical-binding t)

As expected, (let ((x 0)) (lambda () x)) -> (closure ((x . 0) t) nil x)
But, (let ((x 0)) (lambda () 0)) -> (closure ((x . 0) t) nil 0)
And, (lambda (x) x) -> (closure (t) (x) x)

Why do closures' lexical environments include unreferenced symbols? And why 
produce a closure with an empty environment, instead of just a lambda form?

And I have a problem with unwanted closures in minor modes:
(defvar foo-hook nil)
(define-minor-mode bar "Bar" nil " Bar" nil
  (if bar (add-hook 'foo-hook (lambda () (bar 0)) nil t)
    (remove-hook 'foo-hook (lambda () (bar 0)) t)))

M-x bar RET C-h v foo-hook RET, and I get:
foo-hook's value is ((closure
  ((last-message)
   (arg . toggle)
   t)
  nil
  (bar 0))
 t)

Which won't be removed when foo-hook runs, because arg will be 0, not 'toggle. 
I tried to thwart the closure like this:
(defvar foo2-hook nil)
(define-minor-mode bar2 "Bar2" nil " Bar2" nil
  (if bar2 (add-hook 'foo2-hook (let ((arg 0)) (lambda () (bar2 0))) nil t)
    (remove-hook 'foo2-hook (let ((arg 0)) (lambda () (bar2 0))) t)))

M-x bar2 RET C-h v foo2-hook RET, and I get:
foo2-hook's value is ((closure
  ((arg . 0)
   (last-message)
   (arg . toggle)
   t)
  nil
  (bar2 0))
 t)

Argh! Surely this is a misfeature?

Also I don't know why last-message is there, but at least it doesn't interfere.

On a previous experiment that I can't reproduce, involving several additions 
and removals, I got:
Value: ((closure
  ((last-message)
   (arg . 1)
   i t)
  nil
  (bar 0))
 (closure
  ((last-message)
   (arg . 1)
   i t)
  nil
  (bar 0))
 t)

I have no idea what the symbol i means or where it came from. If it were 
setting i to nil in the lexical environment, it would be (i), not i.

Also, the two closures are identical, yet add-hook isn't supposed to add 
duplicates.

Help?




reply via email to

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