emacs-devel
[Top][All Lists]
Advanced

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

RE: Should `cancel-timer' use `delete' instead of `delq'?


From: Drew Adams
Subject: RE: Should `cancel-timer' use `delete' instead of `delq'?
Date: Tue, 5 Sep 2006 23:31:10 -0700

    > I was able to be bitten by it, using C-M-x on the defvar.

    That's a good point, but it's also a very special case -- if you're
    using a debugging command to _force_ a construct to act in an abnormal
    manner, you presumably know what your doing.

Knowing what you're doing, when you think about it, does not always imply
thinking about what you're doing, when you do it. (Yogi Berra only wishes he
had said that.)

    > And the general point applies to setq as well.

    But I think the answer is not a macro, because there's an
    obvious, simple, and extremely widespread idiom for dealing
    with this situation, which every programmer should know
    about (if they don't, they're unlikely to realize they
    should be using the special macro):

       (if var (free-non-gced-thing var))
       (setq var (make-non-gced-thing))

    Not exactly rocket science...

Well, I think that's exactly what I used in my defvar (after having been
bitten once), so I could henceforth re-eval it ("abnormally") without worry
or forethought. In any case, the "traditional" way to do that is apparently
to use `define-minor-mode'...

The point, however, is that it's not that difficult for a programmer to not
think to do that (either one).

People often do learn to use recommended practices (e.g. defvar vs setq,
defcustom vs  defvar, define-minor-mode vs defun). I see no reason why
people wouldn't respond to a recommendation to (usually) use
`define-idle-timer' to define an idle timer. And the logic of the "obvious,
simple, and extremely widespread idiom" that I ultimately used but failed to
use initially, in spite of its patency, would be encapsulated in the macro.

    > To me, it makes sense to have a construct for defining a timer, which
    > doesn't also automatically activate it. Why not separate the
    > two acts, as we do (by default) with advice? As it stands now, to
    > create a timer that is not activated, you must create-and-activate
    > it, and then cancel it.

    Er, there _is_ such a function already: `timer-create'.

Oh, I see. Er, how could I be so ignorant and presumptuous? ;-)

And just how does one pass the necessary information to define an idle timer
to `timer-create'? Isn't it obvious? Here's the complete doc string for that
gem: "Create a timer object." And the complete definition of a timer object
is a length-8 vector. And of course `timer-create' is not mentioned once in
the Emacs-Lisp manual. But thanks for passing it on. Ah, yes, I see now,
`timer-set-idle-time'...

At the end of the day, I really don't care all that much about this. If you
want to help users by fixing up the doc a bit or adding a macro, fine. If
you don't, fine also. If someone brings it up again someday, you can tell
them about `timer-create'.

    But anyway, that doesn't help: the problem is when code "forgets" about
    about an activated timer.  If you do (setq my-timer (timer-create)), and
    the old value of my-timer was an activated timer, you're going to leak
    the old timer even though the new timer is not activated.

Yes, that was my first point, and it is a separate point. It's silly to say
that the one "doesn't help" the other; they are different points.

That the macro could also let you control when and whether to activate the
timer was a second point. I made other suggestions for the macro as well,
including (optionally) defining a toggling command. The separate points can
be examined separately.

    >     Is this potential problem really any more widespread than
    >     millions of other very similar bugs though?  This is exactly
    >     the same as many other sorts of resource allocation/deallocation;
    >
    > Show us the millions of other very similar bugs, and we can
    > compare ;-).

       static char *buf = 0;
       void init_my_package ()
       {buf = malloc (100);...}

    Whoops!

Nah; never bothers me while programming Lisp. But call it #1, anyway, if you
like; only 999,999 to go for your first million. You can throw all of C in
too as widespread similar bug #2, so only 999,998 to go for million #1...

    > I think that one natural, if erroneous, expectation is that
    > the orphan timer will naturally go by the wayside at some point,
    > and need not be thought much about. There are other, just as natural,
    > expectations that would be more correct, but that expectation is a
    > possible and reasonable one: don't worry about that zombie timer;
    > it's history; it may be toast already.

    Huh?  It doesn't seem reasonable or natural at all.

Not to a seasoned adept like yourself, no, of course not. But not all
Emacs-Lisp programmers reach your level.

    Activated timers have an externally visible effect, so clearly
    they can't simply "go away."

Clearly.

    Someone writing code using timers needs to know this.

You mean it's not "obvious, simple, and extremely widespread" knowledge
among all Emacs-Lisp programmers? You think maybe we ought to tell them?






reply via email to

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