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

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

Re: Returning variable "references" under lexical binding


From: Barry Margolin
Subject: Re: Returning variable "references" under lexical binding
Date: Tue, 21 May 2013 10:23:59 -0400
User-agent: MT-NewsWatcher/3.5.3b3 (Intel Mac OS X)

In article <87fvxgc2mz.fsf@gmail.com>, Sean McAfee <eefacm@gmail.com> 
wrote:

> Stefan Monnier <monnier@iro.umontreal.ca> writes:
> >> (defun start-my-timer ()
> >>   (let ((timer (gensym)))
> >>     ;; ... (set timer (make-timer ...)) ...
> >>     timer))
> > [...]
> >> (defun cancel-my-timer (timer)
> >>   (cancel-timer (symbol-value timer)))
> 
> > Why not
> >
> >   (defun start-my-timer ()
> >     (let ((timer (make-timer ...))
> >       ...
> >       timer))
> >   (defun cancel-my-timer (timer)
> >     (cancel-timer timer))
> 
> Because start-my-timer sets up callbacks that may repeatedly change the
> value of the "timer" variable:
> 
> ;; -*- lexical-binding: t; -*-
> 
> (defun start-my-timer ()
>   (let (timer)
>     (setq timer (make-timer ...))
>     ;; ... (later (occasionally (setq timer (make-timer ...)))) ...
>     (lambda () timer))
> 
> Like I said in my original article:
> 
> > It's a routine that sets up a series of idle timers, storing
> > each successive timer object into the same lexical variable.

But it's not the same lexical variable in your example. Each time you 
call start-my-timer you're creating a new closure over that variable. 
The caller has to save that closure somewhere, so that it can pass it to 
cancel-my-timer later. There's no functional difference between that and 
saving the timer itself.

What you're talking about would be using a closure to implement an 
object-oriented approach:

(defun new-timer ()
  (let (timer)
    #'(lambda (operation)
        (case operation
          ((start)
           (setq timer (make-timer ...)))
          ((update)
           (if timer (stop-timer timer))
           (setq timer (make-timer ...)))
          ((stop)
           (if timer (stop-timer timer)))))))

(setq timer (new-timer))
(funcall timer 'start)
(funcall timer 'stop)

-- 
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***


reply via email to

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