merlyn@intelob.intel.com (Randal L. Schwartz @ Stonehenge) (09/21/88)
Elisp suffers from having to have names for all static objects come from one global array. Have you ever wondered just how successful we've been at avoiding having two different elisp packages define the same entries with different meanings? Well, I did. The attached code scans through the lisp and src directories, finding all possible well-behaved insertions into `obarray', and gives a file-and-line-number cross reference for each. Functions and variables are considered separately. Why is this being posted in gnu.emacs.bug? Well, after running this over the 18.50 version, I found some collisions (a few were removed in the 18.51 and 18.52 versions, to which I no longer have immediate access, so I'm not publishing the definitive list). My request is that the powers-that-be run this code before releasing 19.xx (or 18.53) and remove the collisions. For example: `abs' is defined in mim-mode.el, float.el, and cl.el. I very much doubt that the defs in float and cl are compatible. Similarly, `beginning-of-window' is defined in both mlsupport.el and edt.el, `caar' in mh-e.el and cl.el, `caddr' in both doctor.el (!) and cl.el, `cadr' and `cddr' in mh-e.el, doctor.el, and cl.el, `delete-previous-word' in mlsupport.el and edt.el, `line-to-top-of-window' in no less than four places, `lisp-send-defun' in both shell.el and lisp-mode.el, `member' in both doctor.el and cl.el, `mod' in subr.el and cl.el, `setq-default' in data.c and mlsupport.el (hence the need for scanning the C files), `when' in mh-e.el and cl.el. This is not an exaustive list, nor do I have access to 18.52 for the latest test. Caveats: * Code presumes lisp and src directories are siblings of the "exec-directory". * A few collisions are not really. `loaddefs.el' has a lot of setting that gets duplicated in the real files, and some of the C files have duplicate definitions in order to make the DOC file. #ifdef's are also ignored. * Code presumes well-formatted C and Elisp files. See the regexps for details. Enjoy. Comments on my coding style should be sent by mail, please. --- CUT HERE --- (signature is at the end, after the other cut) --- (with-output-to-temp-buffer "*result*" (let ((ob (make-vector 997 0)) (symlist nil)) (mapcar '(lambda (fn) (message "Seeing %s..." fn) (set-buffer (generate-new-buffer " tmp")) (unwind-protect (progn (insert-file-contents fn) (setq fn (file-name-nondirectory fn) case-fold-search nil) (emacs-lisp-mode) (while (re-search-forward (if (string= ".el" (substring fn -3)) "^(\\(defun\\s +\\|defmacro\\s +\\|fset\\s +'\\s *\\)" "^\\s *\\(DEFUN\\|DEFSIMPLE\\|DEFPRED\\)\\s +(\"") nil t) (let ((sym (intern (buffer-substring (prog1 (point) (forward-sexp 1)) (point)) ob))) ;; (message "function %s in %s..." sym fn) (fset sym (cons (format "%s:%d" fn (count-lines (point-min) (point))) (and (fboundp sym) (symbol-function sym)))))) (goto-char (point-min)) (while (re-search-forward (if (string= ".el" (substring fn -3)) "^(\\(defconst\\s +\\|defvar\\s +\\|setq\\s +\\|set\\s +'\\s *\\)" "^\\s *DEFVAR[A-Z_]*\\s +(\"") nil t) (let ((sym (intern (buffer-substring (prog1 (point) (forward-sexp 1)) (point)) ob))) ;; (message "variable %s in %s..." sym fn) (set sym (cons (format "%s:%d" fn (count-lines (point-min) (point))) (and (boundp sym) (symbol-value sym))))))) (kill-buffer (current-buffer)))) (append (directory-files (concat exec-directory "../lisp/") t "\\.el$") (directory-files (concat exec-directory "../src/") t "\\.c$"))) (mapatoms '(lambda (sym) (setq symlist (cons sym symlist))) ob) (setq symlist (sort symlist 'string<)) (mapcar '(lambda (sym) (princ (concat (symbol-name sym) ":\n" (if (fboundp sym) (concat " F: " (mapconcat 'identity (symbol-function sym) " ") "\n") "") (if (boundp sym) (concat " V: " (mapconcat 'identity (symbol-value sym) " ") "\n") "") "\n"))) symlist))) --- CUT HERE --- -- Randal L. Schwartz, Stonehenge Consulting Services (503)777-0095 on contract to BiiN Technical Information Services (for now :-), in a former Intel building in Hillsboro, Oregon, USA <merlyn@intelob.intel.com> or ...!tektronix!inteloa[!intelob]!merlyn Standard disclaimer: I *am* my employer!
gildea@ALEXANDER.BBN.COM (Stephen Gildea) (09/21/88)
Part of the problem is that the Emacs Lisp language is not *quite* rich enough, so writers of different packages feel they have to extend it. I'd like to see more of the primitive Common Lisp functions included by default. Functions I'd propose adding: caar, cadr, cdar, cddr, abs, mapc, mapcar, member, mod, when, and unless. < Stephen
merlyn@intelob.intel.com (Randal L. Schwartz @ Stonehenge) (09/22/88)
In article <8809211547.AA27975@prep.ai.mit.edu>, gildea@ALEXANDER (Stephen Gildea) writes: | Part of the problem is that the Emacs Lisp language is not *quite* | rich enough, so writers of different packages feel they have to extend | it. I'd like to see more of the primitive Common Lisp functions | included by default. | | Functions I'd propose adding: caar, cadr, cdar, cddr, abs, mapc, mapcar, | member, mod, when, and unless. Ahhh. But you see, what you ask for is already there! Try: (progn (require 'cl) (mapcar 'fboundp '(caar cadr cdar cddr abs mapc mapcar member mod when unless)) Unless, what you meant is that "cl" is not loaded by default. Anyway, the "where-defined" tool is useful at least as a guide to how the namespace is already used. Back to my corner, -- Randal L. Schwartz, Stonehenge Consulting Services (503)777-0095 on contract to BiiN Technical Information Services (for now :-), in a former Intel building in Hillsboro, Oregon, USA <merlyn@intelob.intel.com> or ...!tektronix!inteloa[!intelob]!merlyn Standard disclaimer: I *am* my employer!