debug modification of a variable
[elbb.git] / code / elbb.el
blobea7f190bf612bef9b542b781a125d366784f4de9
1 * debug modification of a variable
3 From: Tassilo Horn <tassilo@member.fsf.org>
4 To: emacs-devel@gnu.org
5 Date: Tue, 26 Jan 2010 21:26:49 +0100
6 Subject: Re: How to debug modification to a variable value?
8 "alin.s" <alinsoar@voila.fr> writes:
10 > I suggest you to use the WATCH in gdb for modifications of the
11 > variable, AWATCH for reading of the variable, etc.
13 > To detect the location of the variable is easy: install a breakpoint
14 > in make-variable-buffer-local that stops when exactly the variable you
15 > are interested about is set, then see there the location of
16 > tg-schema-alist. Afterward you can use the x* functions from .gdbinit
17 > of emacs to debug your problem...
19 Thanks for that explanation. I'll try that out as soon as I find some
20 time. And also thanks for volunteering on implementing a debug facility
21 for cases like that.
23 Bye,
24 Tassilo
26 * strip mail head to fit for elbb
28 (defun mail2elbb (&optional beg end)
29 " "
30 (interactive "*")
31 (let ((beg (cond (beg beg)
32 ((region-active-p)
33 (region-beginning))
34 (t (point-min))))
35 (end (cond (end end)
36 ((region-active-p)
37 (copy-marker (region-end)))
38 (t (point-max)))))
39 (save-restriction
40 (narrow-to-region beg end)
41 (goto-char beg)
42 (mail2elbb-intern beg end)
43 (widen))))
45 (defun mail2elbb-intern (beg end)
46 (while (search-forward "=A0" nil t 1)
47 (replace-match ""))
48 (goto-char beg)
49 (let ((end (progn (while
50 (re-search-forward "^[[:alpha:]-]+To:" nil t 1) 't) (copy-marker (line-end-position)))))
51 (goto-char beg)
52 (beginning-of-line)
53 (while
54 (< (point) end)
55 (if (looking-at "Subject:\\|From:\\|Date:\\|To:")
56 (forward-line 1)
57 (delete-region (line-beginning-position) (1+ (line-end-position)))))))
60 * testing configuration
62 From: pjb@informatimago.com (Pascal J. Bourguignon)
63 Date: Sun, 27 Dec 2009 18:53:08 +0100
64 To: help-gnu-emacs@gnu.org
65 Subject: Re: testing configuration
67 andrea <andrea.crotti.0@gmail.com> writes:
69 > I was wondering if it would be possible to automatically check if my
70 > emacs configuration is correct.
71 > This can be then put in a post-commit hook to check that whenever I add
72 > some new features or change I don't mess up somethin else
74 > I would only need to:
75 > - load my whole configuration
76 > - exit and returns 0 if everything goes fine, returns another number
77 > otherwise.
79 > Any ideas?
81 > I can already launch a new emacs with certain conf, but how can I get a
82 > return value?
84 What about:
86 emacs -q --eval '(condition-case err (progn (load "~/.emacs") (kill-emacs 0)) (error (kill-emacs 1)))'
90 --
91 __Pascal Bourguignon__ http://www.informatimago.com/
94 * self-typing
96 From: pjb@informatimago.com (Pascal J. Bourguignon)
97 Date: Sat, 26 Dec 2009 14:32:16 +0100
98 To: help-gnu-emacs@gnu.org
99 Subject: Re: what is `self-typing' ?
101 waterloo <waterloo2005@gmail.com> writes:
103 > I can not understand a para in Elisp manual :
105 > Lisp is unlike many other languages in that its objects are
106 > "self-typing": the primitive type of each object is implicit in the
107 > object itself.  For example, if an object is a vector, nothing can
108 > treat it as a number; Lisp knows it is a vector, not a number.
110 > What is `self-typing' ? thanks
112 As mentionned by Eli. But this require some more explaination.
114 Some languages are defined so that variables can hold only objects of
115 a given type (you declare the type of the variable, or it is infered
116 automatically at compilation time). For example, C or Haskell.
118 Since all the types of the objects are known at compilation time from
119 the variables they're stored in, the compiler doesn't need to generate
120 code to store the type along with the object, or along with the
121 variable: the type is implicity. In C, typeof(42) or int a=42; typeof(a)
122 is computed at compilation time.
124 Some languages are defined so that variables can hold objects of
125 different types, at different times. In that case, the type is not
126 attached to the variable, but must be attached to the objects
127 themselves. For example, Lisp or Smalltalk.
129 Since it is rarely possible to know what type of object a variable
130 will hold (some type inference can still be applied to optimize out
131 some function, but there remains a lot of functions where type
132 inference doesn't restrict much the possible types, the more so when
133 global analysis is not practical or possible), then the type of each
134 object has to be kept with the object. In Lisp, (type-of 42) or (let
135 ((a 42)) (type-of 42)) is computed at run-time. Notably, you can
136 write: (type-of (read)) and depending on what you enter at run-time,
137 will get back one type or another:
139 M-x ielm RET
140 *** Welcome to IELM *** Type (describe-mode) for help.
141 ELISP> (type-of (read))
142 Lisp expression: 42
143 integer
144 ELISP> (type-of (read))
145 Lisp expression: "fourty-two"
146 string
147 ELISP> (type-of (read))
148 Lisp expression: fourty-two
149 symbol
150 ELISP> (type-of (read))
151 Lisp expression: (fourty two)
152 cons
153 ELISP>
155 There are also languages where both things are more or less possible,
156 you can have variables with pre-defined types holding only one type of
157 object, and variables which can hold objects of various types, but of
158 a same root class. For example, C++ or Java.
160 These languages usually provide so called "Plain Old Data" types which
161 correspond to the type of objects that can only be stored in variables
162 with predefined types. These objects of these POD types usually
163 don't have the type attached to them, these objects can only be stored
164 in variables with pre-defined type. When you want to store such an
165 object in a variable-type variable, you have to wrap it in another
166 object, a typed object, instance of a class. In Java, you have a POD
167 type int and an object class Integer.
170 __Pascal Bourguignon__ http://www.informatimago.com/
172 * Emacs uptime
174 From: pjb@informatimago.com (Pascal J. Bourguignon)
175 Date: Wed, 23 Dec 2009 20:16:03 +0100
176 To: help-gnu-emacs@gnu.org
177 Subject: Re: Some functions I hope are useful for others to
179 [ ... ]
181 For example, here is my emacs-uptime:
183 (defvar com.informatimago.time/*emacs-start-time* (current-time)
184 "For (emacs-uptime)")
186 (defun com.informatimago.time/emacs-uptime ()
187 "Gives Emacs' uptime, based on global var `com.informatimago.time/*emacs-start-time*'."
188 (interactive)
189 (let* ((st com.informatimago.time/*emacs-start-time*)
190 (cur (current-time))
191 (hi-diff (- (car cur) (car st)))
192 (tot-sec (+ (ash hi-diff 16) (- (cadr cur) (cadr st))))
193 (days (/ tot-sec (* 60 60 24)))
194 (hrs (/ (- tot-sec (* days 60 60 24)) (* 60 60)))
195 (mins (/ (- tot-sec (* days 60 60 24) (* hrs 60 60)) 60))
196 (secs (/ (- tot-sec (* days 60 60 24) (* hrs 60 60) (* mins 60)) 1)))
197 (message "Up %dd %dh %dm %ds (%s), %d buffers, %d files"
198 days hrs mins secs
199 (format-time-string "%a %Y-%m-%d %T" st)
200 (length (buffer-list))
201 (count t (buffer-list)
202 :test-not
203 (lambda (ignore buf)
204 (null (cdr (assoc 'buffer-file-truename
205 (buffer-local-variables buf)))))))))
207 (defalias 'emacs-uptime 'com.informatimago.time/emacs-uptime)
209 [ .... ]
211 * Using Emacs Lisp for script writing
213 To: help-gnu-emacs@gnu.org
214 From: David Engster <deng@randomsample.de>
215 Date: Sat, 19 Dec 2009 11:02:22 +0100
216 Subject: Re: Using Emacs Lisp for script writing
218 Andreas Politz <politza@fh-trier.de> writes:
219 > Cecil Westerhof <Cecil@decebal.nl> writes:
221 >> I already use 'emacs -batch' for scripting where no user input is used,
222 >> but I would like to use it also for interactive scripting. Until now I
223 >> did not find any usable information about this. Anybody using Emacs for
224 >> interactive scripts?
226 > No, but it should be noted, that this is not very difficult :
228 > $ emacs -Q -batch -eval '(yes-or-no-p "Want some cookies ?")'
230 You can also use the '--script' option in a shebang line:
232 ----------------- test.sh -----------------
233 #!/usr/bin/emacs --script
235 (if (yes-or-no-p "Choose ")
236 (message "You said yes")
237 (message "You said no"))
238 -------------------------------------------
240 I use emacs regularly for writing scripts, since with its thousands of
241 packages you have a huge library readily available.
243 -David
245 * favourite directories implementation
247 Author: Florent Georges, source:
248 http://fgeorges.blogspot.com/2008/01/emacs-favourite-directories.html
250 Today, I have finally taken a look at one of the
251 simple features I always missed in Emacs: the
252 ability to define a set of "favourite directories."
253 That is, a set of named directories that one can use
254 in the minibuffer when prompted for instance to open
255 a file. Given a set of such dirs:
257 emacs-src -> /enter/your/path/to/emacs/sources
258 projects -> /path/to/some/company/projects
259 now -> @projects/the/project/I/am/working/on
261 one can use the following path in the minibuffer to open a file,
262 for instance using C-x C-f:
264 @emacs-src/lisp/files.el
265 @emacs-src/src/alloc.c
266 @projects/great/README
267 @now/src/some/stuff.txt
269 Doing so, completion is available for both directory names and
270 files under their target directories. For instance, to open the
271 third file above, you only have to type:
273 C-x C-f @ p <tab> g <tab> R <tab> <enter>
275 The implementation I have just written is really simple, but
276 useful yet. It implements all described above (including
277 recursive defined directories, as the '@now' above.) Thanks to
278 Emacs, I am still suprised by the facility to implement such a
279 feature!
281 The code was written on GNU Emacs 22.1 on Windows, but should
282 work on any platform, and I think on Emacs 21 as well.
284 TODO: Make a custom variable.
285 (defvar drkm-fav:favourite-directories-alist
286 '(("saxon-src" . "y:/Saxon/saxon-resources9-0-0-1/source/net/sf/saxon")
287 ("kernow-src" . "~/xslt/kernow/svn-2007-09-29/kernow/trunk/src/net/sf/kernow"))
288 "See `drkm-fav:handler'.")
290 (defvar drkm-fav::fav-dirs-re
291 ;; TODO: Is tehre really no other way (than mapcar) to get the list
292 ;; of the keys of an alist?!?
293 (concat
294 "^@"
295 (regexp-opt
296 (mapcar 'car drkm-fav:favourite-directories-alist)
298 "Internal variable that stores a regex computed from
299 `drkm-fav:favourite-directories-alist'. WARNING: This is not
300 updated automatically if the later variable is changed.")
302 (defun drkm-fav:handler (primitive &rest args)
303 "Magic handler for favourite directories.
305 With this handler installed into `file-name-handler-alist', it is
306 possible to use shortcuts for often used directories. It uses
307 the mapping in the alist `drkm-fav:favourite-directories-alist'.
309 Once installed, say you have the following alist in the mapping
310 variable:
312 ((\"dir-1\" . \"~/some/real/dir\")
313 (\"dir-2\" . \"c:/other/dir/for/windows/users\"))
315 You can now use \"@dir-1\" while opening a file with C-x C-f for
316 instance, with completion for the abbreviation names themselves
317 as well as for files under the target directory."
318 (cond
319 ;; expand-file-name
320 ((and (eq primitive 'expand-file-name)
321 (string-match drkm-fav::fav-dirs-re (car args)))
322 (replace-match
323 (cdr (assoc (match-string 1 (car args))
324 drkm-fav:favourite-directories-alist))
325 t t (car args)))
326 ;; file-name-completion
327 ((and (eq primitive 'file-name-completion)
328 (string-match "^@\\([^/]*\\)$" (car args)))
329 (let ((compl (try-completion
330 (match-string 1 (car args))
331 drkm-fav:favourite-directories-alist)))
332 (cond ((eq t compl)
333 (concat "@" (match-string 1 (car args)) "/"))
334 ((not compl)
335 nil)
337 (concat "@" compl)))))
338 ;; file-name-all-completions
339 ((and (eq primitive 'file-name-all-completions)
340 (string-match "^@\\([^/]*\\)$" (car args)))
341 (all-completions
342 (match-string 1 (car args))
343 drkm-fav:favourite-directories-alist))
344 ;; Handle any primitive we don't know about (from the info node
345 ;; (info "(elisp)Magic File Names")).
346 (t (let ((inhibit-file-name-handlers
347 (cons 'drkm-fav:handler
348 (and (eq inhibit-file-name-operation primitive)
349 inhibit-file-name-handlers)))
350 (inhibit-file-name-operation primitive))
351 (apply primitive args)))))
353 ;; Actually plug the feature into Emacs.
354 (push '("\\`@" . drkm-fav:handler) file-name-handler-alist)
356 * lisp interface to ispell
358 From: Teemu Likonen <tlikonen@iki.fi>
359 Date: Fri, 06 Nov 2009 22:05:53 +0200
360 To: help-gnu-emacs@gnu.org
361 Subject: Re: lisp interface to ispell ?
363 On 2009-11-06 20:39 (+0100), Andreas Politz wrote:
365 > Does someone have a hack, or know a different package, in order to allow
366 > elisp access to spelling functions ? E.g. like
368 > (spell word language)
370 > which at least returns t or nil.
372 Something like this?
374 (defun my-ispell-string (word lang)
375 (with-temp-buffer
376 (insert word)
377 (call-process-region (point-min) (point-max)
378 "ispell" t t nil "-l" "-d" lang)
379 (if (= (point-min) (point-max))
380 t)))
382 * Python workflow
384 From: Simon <bbbscarter@gmail.com>
385 Date: Fri, 6 Nov 2009 03:42:44 -0800 (PST)
386 To: help-gnu-emacs@gnu.org
387 Subject: Python workflow
389 Hi, apologies in advance for a potentially numpty post.
391 I've been using Emacs for a little while now, but I've yet to settle
392 on a satisfactory python edit-run-debug cycle, and I was wondering
393 what wiser minds than mine have settled upon. So far I've tried:
395 - Edit code and run with emacs PDB. After fiddling the lisp code to
396 automatically pick up the current buffer as the default run candidate,
397 this is nearly okay. The main issue is that, after editing code,
398 there's no easy way to rerun the code, so I end up killing the gud
399 buffer every time. As such, entering and leaving the debugger is quite
400 a few key presses and accidentally leaving it running is also easy.
402 - Tried Pydb to similar effect.
404 - Run everything in a seperate shell. And debug by hand. This is a
405 little too low-fi, even for me.
407 - Use the 'import/reload file' and 'eval def/class' functions, and run
408 everything from the emacs python shell, using pdbtrack to help with
409 debugging. Problems so far:
410 - It's very easy to forget which modules you've modified and fail to
411 reload them; because the state is carried over I continually find
412 myself running the old versions of code I've just edited, especially
413 if it's across several files.
414 - More than that, sometimes the stuff I expect to reload simply
415 doesn't, and I have no indication as to why. For example, if pdb has
416 module open and you stick a deliberate error in the code and reload
417 it, the minibuffer tells you the module has been loaded, even though
418 it clearly can't have been.
419 - I have to run pdb.pm() to debug the exception. If I run *anything*
420 else by accident, I lose the exception context. This can be annoying
421 if you're incompetent enough to keep making typos (I am).
423 Does anyone have any tips on their workflow?
425 Many thanks!
427 Simon
429 * strip out UTF-8 BOMs
430 From: "Edward O'Connor" <hober0@gmail.com>
431 Date: Thu, 5 Nov 2009 16:13:27 -0800
432 To: emacs-devel@gnu.org
433 Subject: find-file-literally-at-point
437 I recently found myself in need of such a function (I was going through
438 a bunch of files to strip out their UTF-8 BOMs, if you're curious), and
439 it was quick enough to put together:
441 (autoload 'ffap-guesser "ffap")
442 (defun find-file-literally-at-point ()
443 "Open the file at point (like `ffap') with `find-file-literally'."
444 (interactive)
445 (find-file-literally (ffap-guesser)))
447 * xml and n3
449 From: "Eric Schulte" <schulte.eric@gmail.com>
450 Subject: Re: [Orgmode] org-babel-tangle xml text
451 Date: Tue, 03 Nov 2009 09:18:34 -0700
453 "Martin G. Skjæveland" <martige@ifi.uio.no> writes:
455 > Is there a way I can add xml and n3 to the list of supported
456 > languages? These languages does not need interpretation, so I'm
457 > thinking it should be quite easy to add. I have fumblingly tried
459 > (add-to-list 'org-babel-tangle-langs '("xml"))
461 > and
463 > (add-to-list 'org-babel-tangle-langs '("css" "xml"))
465 > but it as no effect.
468 Hi Martin,
470 The attached org-mode file contains instructions for adding xml and n3
471 to org-babel and org-babel-tangle. Note that there may be another step
472 if the major mode for n3 is not n3-mode. Best -- Eric
474 introduce org-babel to =xml= and =n3=
476 #+begin_src emacs-lisp :results silent
477 (org-babel-add-interpreter "xml")
478 (org-babel-add-interpreter "n3")
479 #+end_src
481 if say =n3= should be edited using =xml-mode=, then evaluate the
482 following adding this pair to =org-src-lang-modes=
484 #+begin_src emacs-lisp :results silent
485 (add-to-list 'org-src-lang-modes '("n3" . xml))
486 #+end_src
488 ;; inform org-babel-tangle of their existence and file extensions
489 #+begin_src emacs-lisp :results silent
490 (add-to-list 'org-babel-tangle-langs '("xml" "xml" nil t))
491 (add-to-list 'org-babel-tangle-langs '("n3" "n3" nil t))
492 #+end_src
494 #+begin_src xml :tangle example
495 <first>
496 </first>
497 #+end_src
499 #+begin_src n3 :tangle example
500 n3 stuff
501 #+end_src
503 * How to check regexp for syntax-errors?
505 From: Kevin Rodgers <kevin.d.rodgers@gmail.com>
506 Date: Tue, 20 Oct 2009 01:54:56 -0600
507 Subject: Re: How to check regexp for syntax-errors?
508 David Combs wrote:
509 > Isn't there some .el that that will try to parse a regexp, and tell
510 > me where it got confused, and what to look for for errors?
512 (defun valid-regexp-p (regexp)
513 (interactive "sRegexp: ")
514 (with-temp-buffer
515 (condition-case error-data
516 (progn
517 (re-search-forward regexp nil t)
519 (invalid-regexp
520 (when (interactive-p) (message "Invalid regexp: %s" (cdr error-data)))
521 nil))))
524 Kevin Rodgers
525 Denver, Colorado, USA
527 * prefer cond over case?
529 From: David Kastrup <dak@gnu.org>
530 Date: Mon, 12 Oct 2009 10:03:39 +0200
531 To: help-gnu-emacs@gnu.org
532 Subject: Re: Perferr cond over case?
534 pjb@informatimago.com (Pascal J. Bourguignon) writes:
536 > Nordlöw <per.nordlow@gmail.com> writes:
538 >> Does the use of the cl macro case() incurr some loss of performance
539 >> compare to using cond() instead?
541 > (macroexpand '(case (* 2 2 2 2 3)
542 > (10 'one)
543 > ((24 42) 'two)
544 > ((3 33) 'three)
545 > (otherwise 'unknown)))
546 > -->
547 > (let ((--cl-var-- (* 2 2 2 2 3)))
548 > (cond ((eql --cl-var-- (quote 10)) (quote one))
549 > ((member* --cl-var-- (quote (24 42))) (quote two))
550 > ((member* --cl-var-- (quote (3 33))) (quote three))
551 > (t (quote unknown))))
553 > What do you think?
555 Before or after byte compilation?
558 David Kastrup
560 * batch-mode
562 From: Decebal <cldwesterhof@gmail.com>
563 Newsgroups: gnu.emacs.help
564 Date: Sat, 10 Oct 2009 11:33:17 -0700 (PDT)
565 To: help-gnu-emacs@gnu.org
566 Envelope-To: andreas.roehler@easy-emacs.de
568 In a Bash script I changed:
570 local i
571 local length=${#1}
573 for i in $(seq ${1}) ; do
574 printf " Regel %${length}d voor de test\n" ${i}
575 done >${2}
578 emacs -batch -nw --eval='
579 (let (
581 (nr-of-lines '${1}')
582 (nr-of-lines-length)
583 (output-file "'"${2}"'"))
584 (setq nr-of-lines-length (length (number-to-string nr-of-lines)))
585 (dotimes (i nr-of-lines t)
586 (insert (format (format " Regel %%%dd voor de test\n" nr-of-lines-length) (1+ i))))
587 (write-file output-file))
588 ' 2>/dev/null
590 The Bash version took 293 seconds and the Emacs Lisp version 59
591 seconds. So it is about 5 times as fast.
592 The Emacs batch gives output like:
593 Saving file /home/cecil/temp/inputEmacs...
594 Wrote /home/cecil/temp/inputEmacs
595 That is why I use the 2>/dev/null.
596 Is there a way to circumvent the generation of the above output?
597 Because when there is an error it is also thrown away and that is not
598 nice.
600 From: Vassil Nikolov <vnikolov@pobox.com>
601 Newsgroups: gnu.emacs.help
602 Date: Sat, 10 Oct 2009 16:55:31 -0400
603 To: help-gnu-emacs@gnu.org
604 Envelope-To: andreas.roehler@easy-emacs.de
606 On Sat, 10 Oct 2009 11:33:17 -0700 (PDT), Decebal <cldwesterhof@gmail.com> said:
607 > ...
608 > local i
609 > local length=${#1}
610 > for i in $(seq ${1}) ; do
611 > printf " Regel %${length}d voor de test\n" ${i}
612 > done >${2}
614 translates to
616 emacs -Q -batch -eval '
617 (dotimes (i '"${1}"')
618 (princ (format " Regel %'"${#1}"'d voor de test\n" (1+ i))))
619 ' > "${2}"
621 ---Vassil.
623 From: Decebal <cldwesterhof@gmail.com>
624 Newsgroups: gnu.emacs.help
625 Date: Sat, 10 Oct 2009 13:57:07 -0700 (PDT)
626 To: help-gnu-emacs@gnu.org
627 Envelope-To: andreas.roehler@easy-emacs.de
629 On Oct 10, 10:06pm, Andreas R=F6hler <andreas.roeh...@easy-emacs.de>
630 wrote:
631 > > The Emacs batch gives output like:
632 > > Saving file /home/cecil/temp/inputEmacs...
634 > it's in files.el, save-buffer, AFAIS
636 > (if (and modp (buffer-file-name))
637 > (message "Saving file %s..." (buffer-file-name)))
639 > commenting out these lines should cancel the message
641 The problem with that is that it only works for me. But I found a way.
642 I replaced:
644 (write-file output-file))
646 with:
648 (set-visited-file-name output-file)
649 (basic-save-buffer))
651 But maybe there should be more consideration for the possibility that
652 Emacs is used as a batch program.
654 > > Wrote /home/cecil/temp/inputEmacs
656 I still have to find something for this.
658 That is not possible I am afraid. In the C-source there is a call to
659 message_with_string.
661 * vectors and lists
663 From: pjb@informatimago.com (Pascal J. Bourguignon)
664 Newsgroups: gnu.emacs.help
665 Date: Fri, 09 Oct 2009 19:19:49 +0200
666 To: help-gnu-emacs@gnu.org
667 Envelope-To: andreas.roehler@easy-emacs.de
669 Nordlöw <per.nordlow@gmail.com> writes:
671 > If I have an association list say,
673 > '(
674 > ("key" sym1 val1 num1)
675 > ("key2" sym2 val2 num2)
678 > , where each entry is a fixed sequence of various objects.
680 If this is an a-list, then you could write it as:
682 (("key1" . (sym1 val1 num1))
683 ("key2" . (sym2 val2 numb2)))
685 to show that it is a list of cons cells.
687 (a . (b c d)) <=> (a b c d), but the first notation shows that you
688 consider it as a list of cons, and notably that you don't expect nil
689 ie. () to be in the toplevel of the a-list.
691 Also, if we write the a-list properly like this, we can better answer
692 the following question:
694 > I might
695 > aswell use a vector to represent an entry in this alist, right?
697 You cannot use a vector instead of the cons cells of the a-list, but
698 you can use a vector as a value of an a-list entry. Values can be of
699 any type. In the case of emacs lisp, you could also easily use
700 vectors (or any other type) as keys in an a-list, since it uses equal
701 to compare keys.
703 (("key1" . [sym1 val1 num1])
704 ("key2" . [sym2 val2 num2])
705 ([?k ?e ?y ?3] . [sym3 val3 num3]))
707 > In this case, what do I gain by using a vector instead of list?
709 In general, vectors take half the space of lists, and access to the
710 nth element is done in O(1) instead of O(n) with lists. However,
711 adding or removing an element in a vector is O(n) while in the case of
712 lists, it may be O(1) (prepending an element or removing the first
713 element or one of the few firsts elements) or O(n) (inserting,
714 appending an element or removing the nth element).
716 > What about performance?: aref() faster than nth() only for large
717 > vectors?
719 aref has to compute a multiplication and a sum, before doing one
720 memory load to get the element. In the case of emacs lisp, the
721 multiplication is always by the same fixed factor AFAIK.
723 nth has to do n memory loads to get the element.
725 So indeed, aref will probably be faster than nth, even for indices as
726 small as 1 or 0.
728 > Is there vector-variant of assoc()?
730 No. Unless you count hash-tables as a vector variant.
732 > If not, why?
734 Because there's no point. The advantage of using a list for a-list,
735 apart from the historical simplicity, is that you can easily prepend
736 the a-list with new associations, and therefore use the a-list in a
737 purely functional way.
739 (defun f (bindings)
740 (let ((val (cdr (assoc 'x bindings))))
741 (if (zerop val)
742 (list val)
743 (cons val (f (cons (cons 'x (1- val)) bindings))))))
745 (let ((bindings '((y . 0) (x . 1))))
746 (list (f (cons (cons 'x 2) bindings))
747 (cdr (assoc 'x bindings))))
748 ;; --> ((2 1 0) 1)
750 Note: you could use (require 'cl) (acons key value a-list)
751 instead of (cons (cons key value) a-list).
753 > Has any one already written such a function?
755 Not AFAIK, but you can write it. However, the semantics of assoc
756 require a sequential search of the keys in the list, so there would be
757 no gain. On the contrary, we would now have O(n) complexity to
758 prepend a new entry to the a-vector.
761 __Pascal Bourguignon__