emacs-devel
[Top][All Lists]
Advanced

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

Re: replacing process sentinels and filters with hooks


From: Stephen J. Turnbull
Subject: Re: replacing process sentinels and filters with hooks
Date: Wed, 03 Oct 2012 23:39:47 +0900

Christopher Monsanto writes:

 > I think we are mostly on the same page now. When I say that "I don't
 > want to treat process callbacks specially" and "do we need a different
 > way of doing things?", I'm referring to the fact that add-function and
 > add-hook do similar things

Not really.  The reason why `add-hook' isn't defined as an alias for
`add-to-list' is that hook values are very varied: they can be a list
(including nil), a function, or void, and (independently of the above,
except for void I suppose) they can be global, local, or both.  (I
suspect that the global portion of a hook's value is actually the
shared tail of all the local parts, which would make manipulating hook
values a bit fussy.)

The reason why `add-function' won't be defined as an alias for
`add-to-list' is that it just plain wouldn't work at all (instant
wrong-type-argument, as the values it's intended to operate on are
functions, not lists).

In fact, `add-function' isn't much like `add-hook' at all.  It is far
more similar to what Python expresses with decorator syntax (hm...),
or to `defadvice' itself.

 > For instance, would add-hook be (very lightly-)deprecated in favor
 > of add-function, since add-function is more general than hooks?

No point in deprecation.  `add-function' is not more general, it's
different.  `add-hook' operates on lists, `add-function' on "places"
that hold functions.  Not to mention that `add-function' isn't really
defined yet.

I suppose you could change the APIs for sentinels and filters to be
lists, with basically the same rules as hooks.

 > Hooks could use an interface similar to defadvice to change their
 > arguments: (hook-set-arg <index> <value>) would modify the argument
 > being passed to the next hook.

This is a completely different story from `defadvice'.  Concretely,
why would you want to do that?  Most hook functions don't take
arguments at all.  The ones that do, I can't really see why you would
want to give an altered argument to a random function whose purpose
you don't know.  If you *do* know some function that "needs" edited
args, what's wrong with

(defun decorate (fun)
   `(lambda (&rest args) (apply ,fun (munge args))))

(maplist (lambda (l)
           (if (eq (car l) victim)
               (setcar l (decorate (car l)))))
         whatever-hook)

?

 > My personal preference would be for hook-set-arg, because we wouldn't
 > have two different APIs for callbacks that take arguments, one being
 > more powerful than the other. I can imagine having different APIs
 > might be a problem: consider the case where a library author doesn't
 > know about add-function so they use the hook API.

I think anybody who finds a need to know about something that can
modify other functions' arguments probably is capable of finding the
answer.  `hook-set-arg' is the kind of thing I constitutionally
disagree with, anyway.  Side effects should be avoided when possible.

 > A user complains that they need the ability to modify the arguments
 > passed to the next hook,

"Next hook" or "all remaining hooks"?  Suppose some other code
prepends a new function?  What do you think the user might propose to
do about that?

 > and now the library author has to switch APIs (breaks backward
 > compat) or support two different APIs (breaks maintainer's spirit).

This is inherently fragile, as implied above.  The user already can do
that, anyway:

;; Famous Last Words Department: Untested but should work.
(defun replacement-hook (&rest args)
  (apply 'run-hook-with-args 'user-hook args)
(setq user-hook original-hook)
(setq original-hook nil)
(add-hook 'original-hook #'replacement-hook)

For process sentinels and filters, I can see a relatively simple,
hooklike API.  Perhaps even the hook API, although processes have
their own locality, different from buffers.

I don't really see the need to alter arguments of a function (unless,
like defadvice, you're going to call it yourself, or the function
itself runs a hook to prepare its arguments).  I don't deny that such
needs might exist, but I think it makes sense to leave it up to the
users who find such needs until we have some idea of what kinds of
there are requirements (and how to satisfy them).



reply via email to

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