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