* Removing non `loop' features from cl.el - `cl-map-overlays', `cl-map-intervals', `cl-map-extents'
@ 2010-12-11 22:48 MON KEY
2010-12-12 11:44 ` Stephen J. Turnbull
0 siblings, 1 reply; 3+ messages in thread
From: MON KEY @ 2010-12-11 22:48 UTC (permalink / raw)
To: emacs-devel
cl.el defines `cl-map-extents' as:
(defun cl-map-extents (&rest cl-args)
(apply 'cl-map-overlays cl-args))
AFAICT its only caller is the `loop' macro.
Is there any reason why `cl-map-extents' shouldn't be defaliased to
`cl-map-overlays'?
Changelog circa 1999-12-18 says:
(cl-map-extents): Remove compatibility code.
Also, byte-compiling functions which use the `loop' macro to map overlays or
"intervals" of a buffer causes the byte-compiler to warn spuriously about
calling `cl-map-overlays' and `cl-map-intervals' at runtime.
On GNU Emacs 23.2.1 when evaluating the form below:
(let ((auto-save-default nil)
(make-backup-files nil)
(backup-inhibited nil))
(with-temp-file "./extent-interval-cmpl.el"
(insert
"\n\(eval-when-compile \(require 'cl\)\)
\(defun %loop-interval-or-overlay \(&optional olay-or-interval\)
\(case olay-or-interval
\(overlay
\(loop for ov being the overlays of \(current-buffer\)
collecting ov\)\)
\(interval
\(loop for iv being the intervals of \(current-buffer\)
collecting iv\)\)\)\)
\(defun plain-old-loop \(\)
\(loop for i from 0 to 10 collecting i\)\)
\(provide 'extent-interval-cmpl\)\n"))
(byte-compile-file "./extent-interval-cmpl.el")
(delete-file "./extent-interval-cmpl.el")
(delete-file "./extent-interval-cmpl.elc")
(with-current-buffer (get-buffer-create "*Compile-Log*")
(display-buffer (current-buffer) t)))
Following is what *Compile-Log* has to say about things:
,----
| In %loop-interval-or-overlay:
| extent-interval-cmpl.el:8:23:Warning: Function `cl-map-extents' from cl
| package called at runtime
| extent-interval-cmpl.el:10:16:Warning: assignment to free variable `iv'
| extent-interval-cmpl.el:11:23:Warning: reference to free variable `iv'
| extent-interval-cmpl.el:11:23:Warning: Function `cl-map-intervals' from cl
| package called at runtime
`----
Can anyone else confirm this behavior?
Unless, I've somehow mucked up my cl-*.el files I find these warnings
to be unbelievably bogus!
There is nothing in `cl-map-overlays' nor `cl-map-intervals' which is specific
to Common Lisp, and whatever compatibility code was in `cl-map-extents' has long
since been removed. AFAIK none of these functions have ever been features
provided by Common Lisp and aren't required for compatibility with Common
Lisp. These were features _added_ by cl.el on top of the `loop' macro.
Likewise, none of thes functions require use of CL style keywords so
its not like
there is anything which would suggest that the "cl-" namespacing is
needed. Regardless it certainly shouldn't be causing the byte-compiler to issue
warnings.
My impression is that GNU Emacs' policy on use of `loop' macro is that top-level
functions are allowed to contain loop forms without penalty of the byte-compiler
signalling warnings about their expansion at compile-time. Disregarding
whether the rationale behind this policy is entirely reasonable, it is more than
a little hypocritical to enforce explicit constraints on how and when one may
use a feature distributed _with_ Emacs core (inside the
lisp/emacs-lisp directory)
only to penalize users when they attempt to use some non-Common Lisp
feature that
Emacs strapped onto a Common Lisp compatibility library.
Given the existing prejudiced policy regarding use of cl.el at runtime, TRT to
do w/re these and any other similar such `loop' features not explictity provided
for in the CL spec would be to:
- remove them from the `loop' macro. IOW completely disallow the ability to map
over buffer overlays and intervals, windows, frames, screens, buffers,
etc. as none of thse are specific to Common Lisp either (cf Bug#7492 re
mapping windows and minibuffer frames);
- move `cl-map-overlays', `cl-map-intervals', and `cl-map-extents' into a
different namespace;
- subsitute some other non predjudiced procedure in place of `loop's use of
`cl-map-overlays' and `cl-map-intervals';
- subsitute some other non predjudiece procedure in place of `loop's use of
`cl-map-overlays' and `cl-map-intervals';
From lisp/ in trunk current through bzr revision 102638 rgrep matches for:
;; cl-map-overlays:
./emacs-lisp/cl-extra.el:273:(defun cl-map-overlays (cl-func &optional
cl-buffer cl-start cl-end cl-arg)
./emacs-lisp/cl-extra.el:314:(defalias 'cl-map-extents 'cl-map-overlays)
./emacs-lisp/cl-loaddefs.el:11:;;;;;; cl-map-overlays
cl-map-intervals cl-map-keymap-recursively
./emacs-lisp/cl-loaddefs.el:96:(autoload 'cl-map-overlays "cl-extra" "\
./ChangeLog.9:18443: (cl-map-overlays): Use with-current-buffer.
;; cl-map-intervals:
./emacs-lisp/cl-macs.el:940: `(cl-map-intervals
./emacs-lisp/cl-loaddefs.el:11:;;;;;; cl-map-overlays
cl-map-intervals cl-map-keymap-recursively
./emacs-lisp/cl-loaddefs.el:91:(autoload 'cl-map-intervals "cl-extra" "\
./ChangeLog.9:18441: (cl-map-intervals): Use with-current-buffer.
Don't check for
;; cl-map-extents:
./emacs-lisp/cl-macs.el:915: `(cl-map-extents
./emacs-lisp/cl-extra.el:314:(defalias 'cl-map-extents 'cl-map-overlays)
./ChangeLog.8:268: (cl-map-extents): Remove compatibility code.
--
/s_P\
^ permalink raw reply [flat|nested] 3+ messages in thread
* Removing non `loop' features from cl.el - `cl-map-overlays', `cl-map-intervals', `cl-map-extents'
2010-12-11 22:48 Removing non `loop' features from cl.el - `cl-map-overlays', `cl-map-intervals', `cl-map-extents' MON KEY
@ 2010-12-12 11:44 ` Stephen J. Turnbull
2010-12-12 21:29 ` MON KEY
0 siblings, 1 reply; 3+ messages in thread
From: Stephen J. Turnbull @ 2010-12-12 11:44 UTC (permalink / raw)
To: MON KEY; +Cc: emacs-devel
MON KEY writes:
> cl.el defines `cl-map-extents' as:
>
> (defun cl-map-extents (&rest cl-args)
> (apply 'cl-map-overlays cl-args))
Presumably this function is for compatibility with code written for
XEmacs. I don't see why anybody using GNU Emacs would need it.
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Removing non `loop' features from cl.el - `cl-map-overlays', `cl-map-intervals', `cl-map-extents'
2010-12-12 11:44 ` Stephen J. Turnbull
@ 2010-12-12 21:29 ` MON KEY
0 siblings, 0 replies; 3+ messages in thread
From: MON KEY @ 2010-12-12 21:29 UTC (permalink / raw)
To: Stephen J. Turnbull; +Cc: emacs-devel
On Sun, Dec 12, 2010 at 6:44 AM, Stephen J. Turnbull <stephen@xemacs.org> wrote:
>
> Presumably this function is for compatibility with code written for
> XEmacs. I don't see why anybody using GNU Emacs would need it.
>
Current w/ bzr revision 102585, anybody who uses `loop' w/
"being the overlays of" will run up against `cl-map-extents'.
Whether `cl-map-extents' is a compatibility feature or not does not
change that the GNU Emacs byte-compiler will still complain about it
being called at runtime and it isn't clear that calling
`cl-map-overlays' instead will muffle the byte-compiler whining.
Which is why my example included loop forms which call to both
`cl-map-intervals' and `cl-map-extents' when expanded.
IOW, the issue is that the GNU Emacs byte-compiler warns about these
functions being called at runtime even though as implemented they have
_nothing_ to do with Common Lisp and the warnings have nothing to do
with protecting the "global names".
That `cl-map-extents' got caught up in the mix is (post 1999-12) a
side-effect of the bigger issue. Namely, that if the policy around use
of CL at runtime is to prevent "cl-" namespaced functions from being
called at runtime but that (as currently implemented) the library
itself requires use of banned CL features then either:
- those features should be removed from CL;
- those features should be moved into a non prejudiced namespace;
Again, I am advocating that where the Common Lisp `loop' macro does
not provide formal semantics for use of:
intervals, overlay/extent, vconcating,
buffers, windows, frames, key-bindings, etc.
that these add-ons be removed from elisp implementation of `loop'.
It is disingenuous to persist maintaining the CL runtime ban as a
means of protecting the "global names" while also allowing `loop's
feature creep. If the entire CL regime has the potential to encroach
upon the global namespace then it would hold that any GNU Emacs
extensions to the CL regime has in it this same potential.
Likewise, where such extensions do exist there doesn't seem to be
much will among the existing emacs-devel's to maintain the crept
features. As evidenced here:
,----
|
| From: Glenn Morris
| Subject: Re: bug#7492: 23.2; cl loop over the windows: infinite loop, info doc
| Date: Mon, 29 Nov 2010 19:29:26 -0500
|
| > It's not clear if/when the minibuffer window is included and in which
| > order the iteration is done.
|
| By experiment, the minibuffer is not included, which is why it loops
| forever if you force it to start there. Does the order matter? Anyway,
| it's the order that `next-window' gives.
|
| `loop' can probably be improved, but I suggest using `walk-windows'
| (which has well-defined, flexible behaviour wrt the minibuffer)
| instead and will add a note to cl.texi to this effect.
|
`---- :SEE (URL `http://debbugs.gnu.org/cgi/bugreport.cgi?bug=7492')
It is well and good that this bug is fixed and the manual updated
(Thanks Glenn!), but this doesn't address the underlying problem which
is that when users use the elisp `loop' macro expecting that where its
semantics explicitly provide for an idiom that diverges from the
Common Lisp semantics it should respond reasonably.
My interpretation of RGM's response is that whether the order matters
or not one would do better to use next-window/walk-windows. This is
fine for what its worth but CL `loop'ing needn't be the same as or
only involved of walking a tree of window objects, and in so much as
`next-window' is a C primitive it isn't necessarily clear that
`next-window'/`walk-windows' do have such particularly well defined
behavior wrt the minibuffer at the _lisp_ level (flexible though this
behavior may be).
In any event the suggestion that next-window/walk-windows may be a
better fit for such uses is more than a little amusing given that a
good deal of the "window walking" in src/window.c is oriented around
the heavy lifting of a function named... wait for it... "window_loop"!
Of which most of its branches check MINI_WINDOW_P, e.g. around
UNSHOW_BUFFER, GET_BUFFER_WINDOW, GET_LRU_WINDOW, etc.
Whichever, the point is that it is wrong for the byte-compiler to
penalize them when they use the elisp `loop' macro in a manner that
GNU Emacs lisp provides for. esp. as doubtful few users are looking
at the C in src/window.c when seeking a lispy solution for a window
frobbing task any more than they are looking at lisp/windows.el or
lisp/emacs-lisp/cl-macs.el
So, while its perfectly reasonable for RGM et al to suggest that users
might make better use of the elisp's interface to the underlying C
window machinery it is unreasonable to expect that users be able to
differentiate the relative merits of elisp's next-window/walk-windows
as opposed to its implementation of the Common Lisp `loop' macro.
From the user perspective `walk-windows' and `loop' are each made of
the same lispy goo. How is the user supposed to know that the
`walk-windows' goo is comprised of a more privileged stuff than
`loop's?
Indeed, all else being equal, in terms of perceived utility to users
the goo of the `loop' abstraction is most likely seen as more
privileged than that of `walk-windows'/`next-window':
rgrep in trunk/lisp matches ~335 uses of `loop'
find . -type f -name "*.el" -print0 | xargs -0 -e grep -nH -e "(loop "
rgrep in trunk/lisp matches ~20 uses of `walk-windows'
find . -type f -name "*.el" -print0 | xargs -0 -e grep -nH -e "(walk-windows "
rgrep in trunk/lisp matches ~20 uses of `next-window'
find . -type f -name "*.el" -print0 | xargs -0 -e grep -nH -e '(next-window '
If what the byte-compiler really means to say when it barks:
Warning: Function `<cl-*>' from cl package called at runtime
is actually:
Warning: Function `<cl-*>' from cl package is (as implemented) not as
efficient nor as supported as an equivalent elisp function
implemented by way of a platform specific GNU Emacs C primitive.
Recommend to substitue with `<elisp-fun-name-here>'.
Then that is what it should say.
--
/s_P\
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2010-12-12 21:29 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-12-11 22:48 Removing non `loop' features from cl.el - `cl-map-overlays', `cl-map-intervals', `cl-map-extents' MON KEY
2010-12-12 11:44 ` Stephen J. Turnbull
2010-12-12 21:29 ` MON KEY
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.