until found
[elbb.git] / code / elbb.el
blob4d61a73d783a5801c6eae4da23c9f3d3c73785a9
2 * how to access a large datastructure efficiently?
4 To: help-gnu-emacs@gnu.org
5 From: Thierry Volpiatto <thierry.volpiatto@gmail.com>
6 Date: Thu, 04 Mar 2010 17:09:35 +0100
7 Subject: Re: how to access a large datastructure efficiently?
9 Andreas Röhler <andreas.roehler@easy-emacs.de> writes:
11 > Thierry Volpiatto wrote:
12 >> Andreas Röhler <andreas.roehler@easy-emacs.de> writes:
13 >>
14 >>> Thierry Volpiatto wrote:
15 >>>> Thierry Volpiatto <thierry.volpiatto@gmail.com> writes:
16 >>>>
17 >>>>> Hi,
18 >>>>>
19 >>>>> Christian Wittern <cwittern@gmail.com> writes:
20 >>>>>
21 >>>>>> Hi there,
22 >>>>>>
23 >>>>>> Here is the problem I am trying to solve:
24 >>>>>>
25 >>>>>> I have a large list of items which I want to access. The items are in
26 >>>>>> sequential order, but many are missing in between, like:
27 >>>>>>
28 >>>>>> (1 8 17 23 25 34 45 47 50) [in reality, there is a value associated
29 >>>>>> with this, but I took it out for simplicity]
30 >>>>>>
31 >>>>>> Now when I am trying to access with a key that is not in the list, I
32 >>>>>> want to have the one with the closest smaller key returned, so for 6
33 >>>>>> and 7 this would be 1, but for 8 and 9 this would be 8.
34 >>>>>>
35 >>>>>> Since the list will have thousands of elements, I do not want to simply
36 >>>>>> loop through it but am looking for better ways to do this in Emacs lisp.
37 >>>>>> Any ideas how to achieve this?
38 >>>>> ,----
39 >>>>> | (defun closest-elm-in-seq (n seq)
40 >>>>> | (let ((pair (loop with elm = n with last-elm
41 >>>>> | for i in seq
42 >>>>> | if (and last-elm (< last-elm elm) (> i elm)) return (list last-elm i)
43 >>>>> | do (setq last-elm i))))
44 >>>>> | (if (< (- n (car pair)) (- (cadr pair) n))
45 >>>>> | (car pair) (cadr pair))))
46 >>>>> `----
47 >>>>>
48 >>>>> That return the closest, but not the smaller closest, but it should be
49 >>>>> easy to adapt.
50 >>>> Case where your element is member of list, return it:
51 >>>>
52 >>>> ,----
53 >>>> | (defun closest-elm-in-seq (n seq)
54 >>>> | (let ((pair (loop with elm = n with last-elm
55 >>>> | for i in seq
56 >>>> | if (eq i elm) return (list i)
57 >>>> | else if (and last-elm (< last-elm elm) (> i elm)) return (list last-elm i)
58 >>>> | do (setq last-elm i))))
59 >>>> | (if (> (length pair) 1)
60 >>>> | (if (< (- n (car pair)) (- (cadr pair) n))
61 >>>> | (car pair) (cadr pair))
62 >>>> | (car pair))))
63 >>>> `----
64 >>>> For the smallest just return the car...
65 >>>>
66 >>> if n is member of the seq, maybe equal-operator too
67 >>>
68 >>> (<= last-elm elm)
69 >>>
70 >>> is correct?
71 >>
72 >> No, in this case:
73 >>
74 >> if (eq i elm) return (list i) ==> (i) ; which is n
75 >>
76 >> and finally (car pair) ==> n
77 >>
79 > Hmm, sorry being the imprecise,
80 > aimed at the first form, whose result equals the the second form once implemented this "="
82 Ok, i understand, yes, we can do what you say and it's more elegant, i
83 just notice also i forget to remove a unuseful else:
85 ,----
86 | (defun closest-elm-in-seq (n seq)
87 | (let ((pair (loop with elm = n with last-elm
88 | for i in seq
89 | if (and last-elm (<= last-elm elm) (> i elm)) return (list last-elm i)
90 | do (setq last-elm i))))
91 | (if (< (- n (car pair)) (- (cadr pair) n))
92 | (car pair) (cadr pair))))
93 `----
95 That should work the same.
96 Thanks. ;-)
98 --
99 Thierry Volpiatto
100 Gpg key: http://pgp.mit.edu/
102 To: help-gnu-emacs@gnu.org
103 From: Andreas Politz <politza@fh-trier.de>
104 Date: Thu, 04 Mar 2010 17:49:54 +0100
105 Subject: Re: how to access a large datastructure efficiently?
107 [ ... ]
109 I don't know how hash-table could help in this case, but maybe you want
110 to consider binary trees, as implemented in the avl-tree.el package.
111 Though, there is no function for finding the closest member with respect
112 to some data and a distance-function, but see below.
114 Finding a (closest) member should be constraint in logarithmic time.
116 (require 'avl-tree)
118 (setq avl (avl-tree-create '<))
120 (dotimes (i 2000)
121 (when (= 0 (% i 4))
122 (avl-tree-enter avl i)))
124 (avl-tree-member avl 80)
125 => 80
126 (avl-tree-member avl 70)
127 => nil
129 (defun avl-tree-closest-member (tree data delta-fn)
130 ;; delta-fn : data x data -> Z
131 (flet ((comp-delta (node)
132 (funcall delta-fn data
133 (avl-tree--node-data node))))
134 (let* ((node (avl-tree--root tree))
135 closest
136 (delta most-positive-fixnum)
137 (compare-function (avl-tree--cmpfun tree))
138 found)
139 (while (and node
140 (not found))
141 (when (< (comp-delta node) delta)
142 (setq delta (comp-delta node)
143 closest node))
144 (cond
145 ((funcall compare-function data (avl-tree--node-data node))
146 (setq node (avl-tree--node-left node)))
147 ((funcall compare-function (avl-tree--node-data node) data)
148 (setq node (avl-tree--node-right node)))
150 (setq found t))))
151 (if closest
152 (avl-tree--node-data closest)
153 nil))))
155 (mapcar
156 (lambda (data)
157 (avl-tree-closest-member
158 avl data (lambda (n1 n2)
159 (abs (- n1 n2)))))
160 '(1001 1002 1003 1004))
162 => (1000 1004 1004 1004)
166 * cedet and auto-complete
168 To: help-gnu-emacs@gnu.org
169 From: Richard Riley <rileyrgdev@gmail.com>
170 Date: Tue, 02 Mar 2010 08:26:20 +0100
171 Subject: Re: cedet and auto-complete
173 Richard Riley <rileyrgdev@gmail.com> writes:
175 > Just another quick poll to see if anyone has got the new cedet working
176 > with auto-complete. cedet has developed its own completion UIs but
177 > ideally I would like to use auto-complete as I do in all other
178 > modes. Has anyone a workaround or instructions for allowing this to
179 > work? Unfortunately if you only enable the minimum features which then
180 > turns off the cedet completion mechs, it also turns off the semantic
181 > navigation features which kind of detracts from its usefulness.
183 > Any help or pointer appreciated,
185 > r.
188 OK, user errror to a degree - I have now moved back to company-mode
189 (newer version is available) and made sure it was on the load path
190 before the version that came with nxhtml.
192 Works well.
194 Here is my simple setup which turns on ispell support in text-mode and
195 so works in gnus message modes.
197 (add-to-list 'load-path "~/.emacs.d/company-mode")
198 (require 'company)
199 (add-hook 'text-mode-hook (lambda()(add-to-list 'company-backends 'company-ispell)))
200 (require 'company-ispell)
201 (global-company-mode)
203 This is with cedet 1.0pre7 and company-mode 0.5
205 * hide-show squash-minor-modes
207 From: Thien-Thi Nguyen <ttn@gnuvola.org>
208 To: Andreas Roehler <andreas.roehler@online.de>
209 Subject: Re: hideshow condensed view
210 Date: Thu, 25 Feb 2010 16:21:27 +0100
212 () Andreas Roehler <andreas.roehler@online.de>
213 () Thu, 25 Feb 2010 15:24:24 +0100
215 thanks a lot maintaining hideshow.el.
217 In the last few years, i can't take any credit for its improvement.
218 See Emacs' ChangeLog for those who actually merit the appreciation...
220 Use it as default outline-mode now.
222 Cool.
224 Just one thing remains so far: hs displays an empty
225 line between headers. Would prefer a more condensed
226 view.
228 You must have good eyes (still); i use hideshow not
229 for density but for spaciousness.
231 Might it be possible to introduce a function
232 `hide-all-empty-lines', inclusive a variable which may
233 be customized?
235 Yeah, it would be possible, but i tend to think of empty lines outside
236 the (top-level) blocks as also outside the scope of hideshow. It's like
237 in the book GEB, there is the tree and there is the stuff outside the
238 tree. Get it?
240 I am already troubled by hideshow straying from its conceptual (both
241 meanings) simplicity -- a block is between matching parens, no more no
242 less -- but that's just me...
244 All this is to say, you probably should write a "squash minor mode",
245 which puts the invisible property on an overlay for text that matches
246 the empty line regexp (which of course, could be made customizable), at
247 which point my advice would be to add a hook to `hs-hide-all' to enable
248 this mode.
250 Here's a quick (but tested (lightly)) sketch:
252 (defvar empty-lines-rx "^\\s-*\\(\n\\s-*\\)+")
254 (defvar empty-lines nil
255 "List of empty lines (overlays).")
257 (defvar squash-minor-mode nil)
259 (defun squash-minor-mode ()
260 (interactive)
261 (setq squash-minor-mode (not squash-minor-mode))
262 (if squash-minor-mode
263 (save-excursion
264 (goto-char (point-min))
265 (while (re-search-forward empty-lines-rx nil t)
266 (let ((ov (make-overlay (match-beginning 0) (match-end 0))))
267 (overlay-put ov 'display "")
268 (push ov empty-lines))))
269 (mapc 'delete-overlay empty-lines)
270 (setq empty-lines nil))
271 (message "empty-lines squashing %s" (if squash-minor-mode 'on 'off)))
273 Have fun!
277 * questioning let
279 Andreas Roehler <andreas.roehler@online.de> writes:
281 > Hi,
283 > behaviour of the example code below puzzles me. Would
284 > expect setting of arg by external function, but inside
285 > `let', recognised. But remains `1'.
287 > (defun arg-setting ()
288 > (interactive)
289 > (let ((arg 1))
290 > (message "%s" arg)
291 > (arg-extern arg)
292 > (message "%s" arg)))
294 > (defun arg-extern (arg)
295 > (setq arg (1- arg)))
297 > Any help?
299 From: David Kastrup <dak@gnu.org>
300 Date: Wed, 24 Feb 2010 19:10:38 +0100
301 To: help-gnu-emacs@gnu.org
302 Subject: Re: questioning let
304 >> The argument binding in arg-extern is the innermost one and consequently
305 >> the only affected one. If you make the function argument-less, it will
306 >> likely work as expected by you, affecting the binding in arg-setting.
308 > That works, thanks a lot!
309 > However, stored in some eil.el, get a compiler warning than:
312 > In arg-extern:
313 > eil.el:9:9:Warning: reference to free variable `arg'
314 > eil.el:9:17:Warning: assignment to free variable `arg'
316 > Would think a useless warning, as the compiler should know being inside a let (?)
318 The warning is completely accurate since arg-extern can be called from
319 outside arg-setting, in which case it will assign to a global variable
320 called "arg".
322 Whether or not some let-binding might be effective at the point of
323 calling arg-extern is unknown to the compiler.
325 In a Lisp variant with lexical binding (like Common Lisp or Scheme),
326 arg-extern has no way to fiddle with the let-binding of arg-setting: it
327 is completely inaccessible by name outside of arg-setting itself.
330 David Kastrup
332 From: pjb@informatimago.com (Pascal J. Bourguignon)
333 Date: Wed, 24 Feb 2010 12:59:22 +0100
334 To: help-gnu-emacs@gnu.org
335 Subject: Re: questioning let
337 let is equivalent to lambda:
339 (let ((a 1) (b 2)) (list a b)) <=> ((lambda (a b) (list a b)) 1 2)
341 defun is binding a lambda to a function cell:
343 (defun f (a b) (list a b))
344 <=> (setf (symbol-function 'f) (lambda (a b) (list a b)))
346 Therefore you can see that calling a function defined by defun is a let
347 in disguise.
349 If you transformed your code following these equivalences, you would
350 notice that you have actually TWO variables named arg, one as parameter
351 of the function arg-extern, and one as variable in the let in
352 arg-setting.
354 The setq in arg-extern will modify only the variable parameter of
355 arg-extern. Because they have the same name, this variable hides the
356 one defined in the let of arg-setting. There's no way to access it from
357 within arg-extern.
359 If they had a different name, you could modify a variable from an outer
360 dynamic scope from an inner dynamic scope, because in emacs all the
361 variables are dynamic. But it is considered very bad form to do so:
362 this is a big side effect, and what's more, one that depends on the call
363 chain. You should avoid side effects, to increase the readability and
364 debugability of your code. Therefore you should avoid setq and setf.
365 Try to write pure function, never try to modify a variable.
367 One way to write your code would be:
369 (defun do-what-you-need-to-do-with (arg)
372 (defun arg-binding ()
373 (interactive)
374 (let ((arg 1))
375 (message "before arg = %s" arg)
376 (let ((arg (arg-extern arg)))
377 (message "after arg = %s" arg)
378 (do-what-you-need-to-do-with arg))
379 (message "original arg = %s" arg)))
381 (defun arg-extern (arg)
382 (message "arg-extern before arg = %s" arg)
383 (message "arg-extern returns = %s" (1- arg))
384 (1- arg))
386 before arg = 1
387 arg-extern before arg = 1
388 arg-extern returns = 0
389 after arg = 0
390 original arg = 1
392 If you need a global variable (perhaps because you need to keep some
393 data across command invocations), the I would advise to distringuish it
394 from the other by giving it a name surrounded by stars: *var*. Then, it
395 will have a different name, and won't be shadowed (inadvertantly) by
396 inner lets, defuns or lambdas.
398 (defvar *var* 42)
400 (defun arg-extern (arg)
401 (message "arg-extern before arg = %s" arg)
402 (setf *var* (1- arg))
403 (message "arg-extern returns = %s" *var*)
404 *var*)
406 (arg-binding)
407 var* --> 0
410 __Pascal Bourguignon__
412 * real tab completion in shell-mode
414 To: help-gnu-emacs@gnu.org
415 From: Andreas Politz <politza@fh-trier.de>
416 Date: Tue, 23 Feb 2010 19:43:58 +0100
417 Subject: Re: real tab completion in shell-mode
419 Nathaniel Flath <flat0103@gmail.com> writes:
421 > Hello,
422 > Is there any way to get shell mode to use the background shell's
423 > (zsh or bash) tab completion as opposed to just tab-completing
424 > filenames?  I know about ansi-term, but I hate how it steals a lot
425 > of my keybindings and so I would prefer it if I could get this to
426 > work in shell-mode.
428 There is not really a clean way to implement this for different reasons.
431 > Thanks,
432 > Nathaniel Flath
434 A while ago, I did it anyway and wrote a special mode for bash-shells
435 which features
437 + emulation of bash completion
438 + dir-tracking (local and remote)
439 + tracking of history files
440 + displaying dir stack in header line
442 I took the opportunity to comment the code somewhat, you may give it
443 a try, if you dare:
445 http://www.fh-trier.de/~politza/emacs/bash-mode-1_0.tgz
447 Extract it somewhere in your load-path and read the commentary, or just
448 M-x bash RET
452 * reduce repeated backslashes
454 From: Teemu Likonen <tlikonen@iki.fi>
455 Date: Mon, 15 Feb 2010 10:51:28 +0200
456 To: help-gnu-emacs@gnu.org
457 Subject: Re: reduce repeated backslashes
459 2010-02-15 09:40 (+0100), Andreas Roehler wrote:
461 > don't know how to replace/reduce repeated backslashes from inside a
462 > string.
464 > Let's assume "abcdef\\\\"
466 What is the end result you want? I guess:
468 (replace-regexp-in-string "\\\\\\\\" "\\" "abcdef\\\\" nil t)
469 => "abcdef\\"
471 There are 8 backslashes in the regexp string because backslash is a meta
472 character in Lisp strings and also in regexps. 8 backslashes in a regexp
473 Lisp string means 2 literal backslashes. In the resulting string there
474 is only one backslash but it is displayed as two "\\" because it's a
475 printed representation of Lisp string.
477 * Why can't I use xargs emacs?
479 From: pjb@informatimago.com (Pascal J. Bourguignon)
480 Date: Tue, 02 Feb 2010 23:40:30 +0100
481 To: help-gnu-emacs@gnu.org
482 Subject: Re: Why can't I use xargs emacs?
484 Adam Funk <a24061@ducksburg.com> writes:
486 > The emacs command can take a list of filename arguments, so why can't
487 > I get xargs to work with it?
489 > $ find -name '*.txt' |xargs emacs -nw
490 > emacs: standard input is not a tty
492 > $ grep -rl 'foo' some/path |xargs emacs -nw
493 > emacs: standard input is not a tty
495 emacs is an interactive program. It expects its stdin and stdout to
496 be hooked to the terminal, where it can display a character matrix,
497 and from which it can read user input.
499 When you use a pipe to send paths to xargs, you disconnect the
500 terminal from the stdin, and replace it with a pipe. When xargs forks
501 and exec emacs, emacs inherit this pipe as stdin, and cannot get user
502 input, but will get instead further path from grep.
504 % echo hello > file ; ( echo -b ; echo file ) | xargs -L 1 cat
505 hello
507 To open several files in emacs, you could either use emacsclient, or
508 an emacs lisp script.
510 Launch emacs in a separate terminal: xterm -e emacs -nw &
511 In emacs, start the server: M-x server-start RET
512 In a shell, you can then type: find -name '*.txt' | xargs emacsclient -n
514 Simplier would be to just open the file in emacs:
516 Launch emacs: emacs -nw
517 Then type: C-x C-f *.txt RET
519 For the second case, you could type:
520 M-: (map nil 'find-file (split-string (shell-command-to-string "grep -rl 'foo' some/path") "\n")) RET
523 __Pascal Bourguignon__
525 From: Harald Hanche-Olsen <hanche@math.ntnu.no>
526 Date: Tue, 02 Feb 2010 18:51:39 -0500
527 To: help-gnu-emacs@gnu.org
528 Subject: Re: Why can't I use xargs emacs?
530 + Adam Funk <a24061@ducksburg.com>:
532 > The emacs command can take a list of filename arguments, so why can't
533 > I get xargs to work with it?
535 > $ find -name '*.txt' |xargs emacs -nw
536 > emacs: standard input is not a tty
538 $ find -name '*.txt' |xargs sh -c 'emacs -nw "$@" </dev/tty' -
540 (untested)
543 Harald Hanche-Olsen <URL:http://www.math.ntnu.no/~hanche/>
544 - It is undesirable to believe a proposition
545 when there is no ground whatsoever for supposing it is true.
546 -- Bertrand Russell
548 To: help-gnu-emacs@gnu.org
549 From: Thierry Volpiatto <thierry.volpiatto@gmail.com>
550 Date: Wed, 03 Feb 2010 08:23:52 +0100
551 Subject: Re: Why can't I use xargs emacs?
553 Why not a simple:
555 emacs -nw -Q $(find . -name '*.txt')
557 Why do you want to use xargs?
559 Bill Marcum <marcumbill@bellsouth.net> writes:
561 > ["Followup-To:" header set to comp.unix.shell.]
562 > On 2010-02-02, Adam Funk <a24061@ducksburg.com> wrote:
563 >> The emacs command can take a list of filename arguments, so why can't
564 >> I get xargs to work with it?
566 >> $ find -name '*.txt' |xargs emacs -nw
567 >> emacs: standard input is not a tty
569 >> $ grep -rl 'foo' some/path |xargs emacs -nw
570 >> emacs: standard input is not a tty
572 > It says: standard input is not a tty. I don't normally use emacs, so there
573 > may be a better way to do this, but you could write a function:
574 > my_emacs () { emacs "$@" </dev/tty >&0 2>&0 ; }
579 Thierry Volpiatto
581 From: Adam Funk <a24061@ducksburg.com>
582 Date: Wed, 03 Feb 2010 14:18:58 +0000
583 To: help-gnu-emacs@gnu.org
584 Subject: Re: Why can't I use xargs emacs?
586 On 2010-02-02, Bit Twister wrote:
588 > On Tue, 02 Feb 2010 20:22:17 +0000, Adam Funk wrote:
589 >> The emacs command can take a list of filename arguments, so why can't
590 >> I get xargs to work with it?
592 >> $ find -name '*.txt' |xargs emacs -nw
593 >> emacs: standard input is not a tty
595 >> $ grep -rl 'foo' some/path |xargs emacs -nw
596 >> emacs: standard input is not a tty
599 > Maybe it's the -nw switch. Try
600 > find -name '*.txt' |xargs emacs
602 Yes, it works without -nw, but I'm often logged into an ssh server so
603 it's faster to open emacs in the xterm.
605 Anyway, the solution (posted by Thierry in gnu.emacs.help) turns out
606 to be this:
608 emacs -nw $(find . -name '*.txt')
610 Thanks.
613 ..the reason why so many professional artists drink a lot is not
614 necessarily very much to do with the artistic temperament, etc. It is
615 simply that they can afford to, because they can normally take a large
616 part of a day off to deal with the ravages. [Amis _On Drink_]
618 * getting emacs from launchpad
620 From: Lennart Borgman <lennart.borgman@gmail.com>
621 Date: Tue, 26 Jan 2010 22:46:47 +0100
622 To: henry atting <nsmp_01@online.de>
623 Subject: Re: bazaar question
625 On Tue, Jan 26, 2010 at 10:31 PM, henry atting <nsmp_01@online.de> wrote:
626 > I find it annoying that I have to grapple with bazaar if I
627 > want to go on building emacs from source. Do I really have to pull
628 > the whole emacs tree starting from the first published sources in the
629 > Roman Empire?
631 > Tried it with `bazaar branch http://bzr.savannah.gnu.org/r/emacs/trunk/'
632 > but stopped, unpatiently, after 20 minutes.
633 > Is this the only way to get the latest source?
635 You can get them from Launchpad too. That is faster since they have
636 installed the bazaar fast server (or what it is called).
638 bzr branch lp:emacs trunk
640 After that updates are quick (in the trunk subdir):
642 bzr update
644 * debug modification of a variable
646 From: Tassilo Horn <tassilo@member.fsf.org>
647 To: emacs-devel@gnu.org
648 Date: Tue, 26 Jan 2010 21:26:49 +0100
649 Subject: Re: How to debug modification to a variable value?
651 "alin.s" <alinsoar@voila.fr> writes:
653 > I suggest you to use the WATCH in gdb for modifications of the
654 > variable, AWATCH for reading of the variable, etc.
656 > To detect the location of the variable is easy: install a breakpoint
657 > in make-variable-buffer-local that stops when exactly the variable you
658 > are interested about is set, then see there the location of
659 > tg-schema-alist. Afterward you can use the x* functions from .gdbinit
660 > of emacs to debug your problem...
662 Thanks for that explanation. I'll try that out as soon as I find some
663 time. And also thanks for volunteering on implementing a debug facility
664 for cases like that.
666 Bye,
667 Tassilo
669 * strip mail head to fit for elbb
671 (defun mail2elbb (&optional beg end)
673 (interactive "*")
674 (let ((beg (cond (beg beg)
675 ((region-active-p)
676 (region-beginning))
677 (t (point-min))))
678 (end (cond (end end)
679 ((region-active-p)
680 (copy-marker (region-end)))
681 (t (point-max)))))
682 (save-restriction
683 (narrow-to-region beg end)
684 (goto-char beg)
685 (mail2elbb-intern beg end)
686 (widen))))
688 (defun mail2elbb-intern (beg end)
689 (while (search-forward "=A0" nil t 1)
690 (replace-match ""))
691 (goto-char beg)
692 (let ((end (progn (while
693 (re-search-forward "^[[:alpha:]-]+To:" nil t 1) 't) (copy-marker (line-end-position)))))
694 (goto-char beg)
695 (beginning-of-line)
696 (while
697 (< (point) end)
698 (if (looking-at "Subject:\\|From:\\|Date:\\|To:")
699 (forward-line 1)
700 (delete-region (line-beginning-position) (1+ (line-end-position)))))))
702 * testing configuration
704 From: pjb@informatimago.com (Pascal J. Bourguignon)
705 Date: Sun, 27 Dec 2009 18:53:08 +0100
706 To: help-gnu-emacs@gnu.org
707 Subject: Re: testing configuration
709 andrea <andrea.crotti.0@gmail.com> writes:
711 > I was wondering if it would be possible to automatically check if my
712 > emacs configuration is correct.
713 > This can be then put in a post-commit hook to check that whenever I add
714 > some new features or change I don't mess up somethin else
716 > I would only need to:
717 > - load my whole configuration
718 > - exit and returns 0 if everything goes fine, returns another number
719 > otherwise.
721 > Any ideas?
723 > I can already launch a new emacs with certain conf, but how can I get a
724 > return value?
726 What about:
728 emacs -q --eval '(condition-case err (progn (load "~/.emacs") (kill-emacs 0)) (error (kill-emacs 1)))'
733 __Pascal Bourguignon__ http://www.informatimago.com/
735 * self-typing
737 From: pjb@informatimago.com (Pascal J. Bourguignon)
738 Date: Sat, 26 Dec 2009 14:32:16 +0100
739 To: help-gnu-emacs@gnu.org
740 Subject: Re: what is `self-typing' ?
742 waterloo <waterloo2005@gmail.com> writes:
744 > I can not understand a para in Elisp manual :
746 > Lisp is unlike many other languages in that its objects are
747 > "self-typing": the primitive type of each object is implicit in the
748 > object itself.  For example, if an object is a vector, nothing can
749 > treat it as a number; Lisp knows it is a vector, not a number.
751 > What is `self-typing' ? thanks
753 As mentionned by Eli. But this require some more explaination.
755 Some languages are defined so that variables can hold only objects of
756 a given type (you declare the type of the variable, or it is infered
757 automatically at compilation time). For example, C or Haskell.
759 Since all the types of the objects are known at compilation time from
760 the variables they're stored in, the compiler doesn't need to generate
761 code to store the type along with the object, or along with the
762 variable: the type is implicity. In C, typeof(42) or int a=42; typeof(a)
763 is computed at compilation time.
765 Some languages are defined so that variables can hold objects of
766 different types, at different times. In that case, the type is not
767 attached to the variable, but must be attached to the objects
768 themselves. For example, Lisp or Smalltalk.
770 Since it is rarely possible to know what type of object a variable
771 will hold (some type inference can still be applied to optimize out
772 some function, but there remains a lot of functions where type
773 inference doesn't restrict much the possible types, the more so when
774 global analysis is not practical or possible), then the type of each
775 object has to be kept with the object. In Lisp, (type-of 42) or (let
776 ((a 42)) (type-of 42)) is computed at run-time. Notably, you can
777 write: (type-of (read)) and depending on what you enter at run-time,
778 will get back one type or another:
780 M-x ielm RET
781 *** Welcome to IELM *** Type (describe-mode) for help.
782 ELISP> (type-of (read))
783 Lisp expression: 42
784 integer
785 ELISP> (type-of (read))
786 Lisp expression: "fourty-two"
787 string
788 ELISP> (type-of (read))
789 Lisp expression: fourty-two
790 symbol
791 ELISP> (type-of (read))
792 Lisp expression: (fourty two)
793 cons
794 ELISP>
796 There are also languages where both things are more or less possible,
797 you can have variables with pre-defined types holding only one type of
798 object, and variables which can hold objects of various types, but of
799 a same root class. For example, C++ or Java.
801 These languages usually provide so called "Plain Old Data" types which
802 correspond to the type of objects that can only be stored in variables
803 with predefined types. These objects of these POD types usually
804 don't have the type attached to them, these objects can only be stored
805 in variables with pre-defined type. When you want to store such an
806 object in a variable-type variable, you have to wrap it in another
807 object, a typed object, instance of a class. In Java, you have a POD
808 type int and an object class Integer.
811 __Pascal Bourguignon__ http://www.informatimago.com/
813 * Emacs uptime
815 From: pjb@informatimago.com (Pascal J. Bourguignon)
816 Date: Wed, 23 Dec 2009 20:16:03 +0100
817 To: help-gnu-emacs@gnu.org
818 Subject: Re: Some functions I hope are useful for others to
820 [ ... ]
822 For example, here is my emacs-uptime:
824 (defvar com.informatimago.time/*emacs-start-time* (current-time)
825 "For (emacs-uptime)")
827 (defun com.informatimago.time/emacs-uptime ()
828 "Gives Emacs' uptime, based on global var `com.informatimago.time/*emacs-start-time*'."
829 (interactive)
830 (let* ((st com.informatimago.time/*emacs-start-time*)
831 (cur (current-time))
832 (hi-diff (- (car cur) (car st)))
833 (tot-sec (+ (ash hi-diff 16) (- (cadr cur) (cadr st))))
834 (days (/ tot-sec (* 60 60 24)))
835 (hrs (/ (- tot-sec (* days 60 60 24)) (* 60 60)))
836 (mins (/ (- tot-sec (* days 60 60 24) (* hrs 60 60)) 60))
837 (secs (/ (- tot-sec (* days 60 60 24) (* hrs 60 60) (* mins 60)) 1)))
838 (message "Up %dd %dh %dm %ds (%s), %d buffers, %d files"
839 days hrs mins secs
840 (format-time-string "%a %Y-%m-%d %T" st)
841 (length (buffer-list))
842 (count t (buffer-list)
843 :test-not
844 (lambda (ignore buf)
845 (null (cdr (assoc 'buffer-file-truename
846 (buffer-local-variables buf)))))))))
848 (defalias 'emacs-uptime 'com.informatimago.time/emacs-uptime)
850 [ .... ]
852 * Using Emacs Lisp for script writing
854 To: help-gnu-emacs@gnu.org
855 From: David Engster <deng@randomsample.de>
856 Date: Sat, 19 Dec 2009 11:02:22 +0100
857 Subject: Re: Using Emacs Lisp for script writing
859 Andreas Politz <politza@fh-trier.de> writes:
860 > Cecil Westerhof <Cecil@decebal.nl> writes:
862 >> I already use 'emacs -batch' for scripting where no user input is used,
863 >> but I would like to use it also for interactive scripting. Until now I
864 >> did not find any usable information about this. Anybody using Emacs for
865 >> interactive scripts?
867 > No, but it should be noted, that this is not very difficult :
869 > $ emacs -Q -batch -eval '(yes-or-no-p "Want some cookies ?")'
871 You can also use the '--script' option in a shebang line:
873 ----------------- test.sh -----------------
874 #!/usr/bin/emacs --script
876 (if (yes-or-no-p "Choose ")
877 (message "You said yes")
878 (message "You said no"))
879 -------------------------------------------
881 I use emacs regularly for writing scripts, since with its thousands of
882 packages you have a huge library readily available.
884 -David
886 * until found
888 From: Helmut Eller
889 Subject: Re: until-found
890 Date: Fri, 11 Dec 2009 17:10:38 +0100
891 User-agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1.50 (gnu/linux)
893 * Andreas Roehler [2009-12-10 13:50+0100] writes:
895 > And here my implementation so far:
897 > (defun until-found (search-string liste)
898 > (let ((liste liste) element)
899 > (while liste
900 > (if (member search-string (car liste))
901 > (setq element (car liste) liste nil))
902 > (setq liste (cdr liste)))
903 > element))
905 This seems to be the same as:
907 (car (member (lambda (element) (member search-string element)) liste))
911 (find-if (lambda (element) (member search-string element)) liste)
915 (find search-string liste :test #'member)
919 (loop for e in liste if (member search-string e) return e)
921 Helmut
923 * favourite directories implementation
925 Author: Florent Georges, source:
926 http://fgeorges.blogspot.com/2008/01/emacs-favourite-directories.html
928 Today, I have finally taken a look at one of the
929 simple features I always missed in Emacs: the
930 ability to define a set of "favourite directories."
931 That is, a set of named directories that one can use
932 in the minibuffer when prompted for instance to open
933 a file. Given a set of such dirs:
935 emacs-src -> /enter/your/path/to/emacs/sources
936 projects -> /path/to/some/company/projects
937 now -> @projects/the/project/I/am/working/on
939 one can use the following path in the minibuffer to open a file,
940 for instance using C-x C-f:
942 @emacs-src/lisp/files.el
943 @emacs-src/src/alloc.c
944 @projects/great/README
945 @now/src/some/stuff.txt
947 Doing so, completion is available for both directory names and
948 files under their target directories. For instance, to open the
949 third file above, you only have to type:
951 C-x C-f @ p <tab> g <tab> R <tab> <enter>
953 The implementation I have just written is really simple, but
954 useful yet. It implements all described above (including
955 recursive defined directories, as the '@now' above.) Thanks to
956 Emacs, I am still suprised by the facility to implement such a
957 feature!
959 The code was written on GNU Emacs 22.1 on Windows, but should
960 work on any platform, and I think on Emacs 21 as well.
962 TODO: Make a custom variable.
963 (defvar drkm-fav:favourite-directories-alist
964 '(("saxon-src" . "y:/Saxon/saxon-resources9-0-0-1/source/net/sf/saxon")
965 ("kernow-src" . "~/xslt/kernow/svn-2007-09-29/kernow/trunk/src/net/sf/kernow"))
966 "See `drkm-fav:handler'.")
968 (defvar drkm-fav::fav-dirs-re
969 ;; TODO: Is tehre really no other way (than mapcar) to get the list
970 ;; of the keys of an alist?!?
971 (concat
972 "^@"
973 (regexp-opt
974 (mapcar 'car drkm-fav:favourite-directories-alist)
976 "Internal variable that stores a regex computed from
977 `drkm-fav:favourite-directories-alist'. WARNING: This is not
978 updated automatically if the later variable is changed.")
980 (defun drkm-fav:handler (primitive &rest args)
981 "Magic handler for favourite directories.
983 With this handler installed into `file-name-handler-alist', it is
984 possible to use shortcuts for often used directories. It uses
985 the mapping in the alist `drkm-fav:favourite-directories-alist'.
987 Once installed, say you have the following alist in the mapping
988 variable:
990 ((\"dir-1\" . \"~/some/real/dir\")
991 (\"dir-2\" . \"c:/other/dir/for/windows/users\"))
993 You can now use \"@dir-1\" while opening a file with C-x C-f for
994 instance, with completion for the abbreviation names themselves
995 as well as for files under the target directory."
996 (cond
997 ;; expand-file-name
998 ((and (eq primitive 'expand-file-name)
999 (string-match drkm-fav::fav-dirs-re (car args)))
1000 (replace-match
1001 (cdr (assoc (match-string 1 (car args))
1002 drkm-fav:favourite-directories-alist))
1003 t t (car args)))
1004 ;; file-name-completion
1005 ((and (eq primitive 'file-name-completion)
1006 (string-match "^@\\([^/]*\\)$" (car args)))
1007 (let ((compl (try-completion
1008 (match-string 1 (car args))
1009 drkm-fav:favourite-directories-alist)))
1010 (cond ((eq t compl)
1011 (concat "@" (match-string 1 (car args)) "/"))
1012 ((not compl)
1013 nil)
1015 (concat "@" compl)))))
1016 ;; file-name-all-completions
1017 ((and (eq primitive 'file-name-all-completions)
1018 (string-match "^@\\([^/]*\\)$" (car args)))
1019 (all-completions
1020 (match-string 1 (car args))
1021 drkm-fav:favourite-directories-alist))
1022 ;; Handle any primitive we don't know about (from the info node
1023 ;; (info "(elisp)Magic File Names")).
1024 (t (let ((inhibit-file-name-handlers
1025 (cons 'drkm-fav:handler
1026 (and (eq inhibit-file-name-operation primitive)
1027 inhibit-file-name-handlers)))
1028 (inhibit-file-name-operation primitive))
1029 (apply primitive args)))))
1031 ;; Actually plug the feature into Emacs.
1032 (push '("\\`@" . drkm-fav:handler) file-name-handler-alist)
1034 * lisp interface to ispell
1036 From: Teemu Likonen <tlikonen@iki.fi>
1037 Date: Fri, 06 Nov 2009 22:05:53 +0200
1038 To: help-gnu-emacs@gnu.org
1039 Subject: Re: lisp interface to ispell ?
1041 On 2009-11-06 20:39 (+0100), Andreas Politz wrote:
1043 > Does someone have a hack, or know a different package, in order to allow
1044 > elisp access to spelling functions ? E.g. like
1046 > (spell word language)
1048 > which at least returns t or nil.
1050 Something like this?
1052 (defun my-ispell-string (word lang)
1053 (with-temp-buffer
1054 (insert word)
1055 (call-process-region (point-min) (point-max)
1056 "ispell" t t nil "-l" "-d" lang)
1057 (if (= (point-min) (point-max))
1058 t)))
1060 * Python workflow
1062 From: Simon <bbbscarter@gmail.com>
1063 Date: Fri, 6 Nov 2009 03:42:44 -0800 (PST)
1064 To: help-gnu-emacs@gnu.org
1065 Subject: Python workflow
1067 Hi, apologies in advance for a potentially numpty post.
1069 I've been using Emacs for a little while now, but I've yet to settle
1070 on a satisfactory python edit-run-debug cycle, and I was wondering
1071 what wiser minds than mine have settled upon. So far I've tried:
1073 - Edit code and run with emacs PDB. After fiddling the lisp code to
1074 automatically pick up the current buffer as the default run candidate,
1075 this is nearly okay. The main issue is that, after editing code,
1076 there's no easy way to rerun the code, so I end up killing the gud
1077 buffer every time. As such, entering and leaving the debugger is quite
1078 a few key presses and accidentally leaving it running is also easy.
1080 - Tried Pydb to similar effect.
1082 - Run everything in a seperate shell. And debug by hand. This is a
1083 little too low-fi, even for me.
1085 - Use the 'import/reload file' and 'eval def/class' functions, and run
1086 everything from the emacs python shell, using pdbtrack to help with
1087 debugging. Problems so far:
1088 - It's very easy to forget which modules you've modified and fail to
1089 reload them; because the state is carried over I continually find
1090 myself running the old versions of code I've just edited, especially
1091 if it's across several files.
1092 - More than that, sometimes the stuff I expect to reload simply
1093 doesn't, and I have no indication as to why. For example, if pdb has
1094 module open and you stick a deliberate error in the code and reload
1095 it, the minibuffer tells you the module has been loaded, even though
1096 it clearly can't have been.
1097 - I have to run pdb.pm() to debug the exception. If I run *anything*
1098 else by accident, I lose the exception context. This can be annoying
1099 if you're incompetent enough to keep making typos (I am).
1101 Does anyone have any tips on their workflow?
1103 Many thanks!
1105 Simon
1107 * strip out UTF-8 BOMs
1108 From: "Edward O'Connor" <hober0@gmail.com>
1109 Date: Thu, 5 Nov 2009 16:13:27 -0800
1110 To: emacs-devel@gnu.org
1111 Subject: find-file-literally-at-point
1115 I recently found myself in need of such a function (I was going through
1116 a bunch of files to strip out their UTF-8 BOMs, if you're curious), and
1117 it was quick enough to put together:
1119 (autoload 'ffap-guesser "ffap")
1120 (defun find-file-literally-at-point ()
1121 "Open the file at point (like `ffap') with `find-file-literally'."
1122 (interactive)
1123 (find-file-literally (ffap-guesser)))
1125 * xml and n3
1127 From: "Eric Schulte" <schulte.eric@gmail.com>
1128 Subject: Re: [Orgmode] org-babel-tangle xml text
1129 Date: Tue, 03 Nov 2009 09:18:34 -0700
1131 "Martin G. Skjæveland" <martige@ifi.uio.no> writes:
1133 > Is there a way I can add xml and n3 to the list of supported
1134 > languages? These languages does not need interpretation, so I'm
1135 > thinking it should be quite easy to add. I have fumblingly tried
1137 > (add-to-list 'org-babel-tangle-langs '("xml"))
1139 > and
1141 > (add-to-list 'org-babel-tangle-langs '("css" "xml"))
1143 > but it as no effect.
1146 Hi Martin,
1148 The attached org-mode file contains instructions for adding xml and n3
1149 to org-babel and org-babel-tangle. Note that there may be another step
1150 if the major mode for n3 is not n3-mode. Best -- Eric
1152 introduce org-babel to =xml= and =n3=
1154 #+begin_src emacs-lisp :results silent
1155 (org-babel-add-interpreter "xml")
1156 (org-babel-add-interpreter "n3")
1157 #+end_src
1159 if say =n3= should be edited using =xml-mode=, then evaluate the
1160 following adding this pair to =org-src-lang-modes=
1162 #+begin_src emacs-lisp :results silent
1163 (add-to-list 'org-src-lang-modes '("n3" . xml))
1164 #+end_src
1166 ;; inform org-babel-tangle of their existence and file extensions
1167 #+begin_src emacs-lisp :results silent
1168 (add-to-list 'org-babel-tangle-langs '("xml" "xml" nil t))
1169 (add-to-list 'org-babel-tangle-langs '("n3" "n3" nil t))
1170 #+end_src
1172 #+begin_src xml :tangle example
1173 <first>
1174 </first>
1175 #+end_src
1177 #+begin_src n3 :tangle example
1178 n3 stuff
1179 #+end_src
1181 * How to check regexp for syntax-errors?
1183 From: Kevin Rodgers <kevin.d.rodgers@gmail.com>
1184 Date: Tue, 20 Oct 2009 01:54:56 -0600
1185 Subject: Re: How to check regexp for syntax-errors?
1186 David Combs wrote:
1187 > Isn't there some .el that that will try to parse a regexp, and tell
1188 > me where it got confused, and what to look for for errors?
1190 (defun valid-regexp-p (regexp)
1191 (interactive "sRegexp: ")
1192 (with-temp-buffer
1193 (condition-case error-data
1194 (progn
1195 (re-search-forward regexp nil t)
1197 (invalid-regexp
1198 (when (interactive-p) (message "Invalid regexp: %s" (cdr error-data)))
1199 nil))))
1202 Kevin Rodgers
1203 Denver, Colorado, USA
1205 * prefer cond over case?
1207 From: David Kastrup <dak@gnu.org>
1208 Date: Mon, 12 Oct 2009 10:03:39 +0200
1209 To: help-gnu-emacs@gnu.org
1210 Subject: Re: Perferr cond over case?
1212 pjb@informatimago.com (Pascal J. Bourguignon) writes:
1214 > Nordlöw <per.nordlow@gmail.com> writes:
1216 >> Does the use of the cl macro case() incurr some loss of performance
1217 >> compare to using cond() instead?
1219 > (macroexpand '(case (* 2 2 2 2 3)
1220 > (10 'one)
1221 > ((24 42) 'two)
1222 > ((3 33) 'three)
1223 > (otherwise 'unknown)))
1224 > -->
1225 > (let ((--cl-var-- (* 2 2 2 2 3)))
1226 > (cond ((eql --cl-var-- (quote 10)) (quote one))
1227 > ((member* --cl-var-- (quote (24 42))) (quote two))
1228 > ((member* --cl-var-- (quote (3 33))) (quote three))
1229 > (t (quote unknown))))
1231 > What do you think?
1233 Before or after byte compilation?
1236 David Kastrup
1238 * batch-mode
1240 From: Decebal <cldwesterhof@gmail.com>
1241 Newsgroups: gnu.emacs.help
1242 Date: Sat, 10 Oct 2009 11:33:17 -0700 (PDT)
1243 To: help-gnu-emacs@gnu.org
1244 Envelope-To: andreas.roehler@easy-emacs.de
1246 In a Bash script I changed:
1248 local i
1249 local length=${#1}
1251 for i in $(seq ${1}) ; do
1252 printf " Regel %${length}d voor de test\n" ${i}
1253 done >${2}
1256 emacs -batch -nw --eval='
1257 (let (
1259 (nr-of-lines '${1}')
1260 (nr-of-lines-length)
1261 (output-file "'"${2}"'"))
1262 (setq nr-of-lines-length (length (number-to-string nr-of-lines)))
1263 (dotimes (i nr-of-lines t)
1264 (insert (format (format " Regel %%%dd voor de test\n" nr-of-lines-length) (1+ i))))
1265 (write-file output-file))
1266 ' 2>/dev/null
1268 The Bash version took 293 seconds and the Emacs Lisp version 59
1269 seconds. So it is about 5 times as fast.
1270 The Emacs batch gives output like:
1271 Saving file /home/cecil/temp/inputEmacs...
1272 Wrote /home/cecil/temp/inputEmacs
1273 That is why I use the 2>/dev/null.
1274 Is there a way to circumvent the generation of the above output?
1275 Because when there is an error it is also thrown away and that is not
1276 nice.
1278 From: Vassil Nikolov <vnikolov@pobox.com>
1279 Newsgroups: gnu.emacs.help
1280 Date: Sat, 10 Oct 2009 16:55:31 -0400
1281 To: help-gnu-emacs@gnu.org
1282 Envelope-To: andreas.roehler@easy-emacs.de
1284 On Sat, 10 Oct 2009 11:33:17 -0700 (PDT), Decebal <cldwesterhof@gmail.com> said:
1285 > ...
1286 > local i
1287 > local length=${#1}
1288 > for i in $(seq ${1}) ; do
1289 > printf " Regel %${length}d voor de test\n" ${i}
1290 > done >${2}
1292 translates to
1294 emacs -Q -batch -eval '
1295 (dotimes (i '"${1}"')
1296 (princ (format " Regel %'"${#1}"'d voor de test\n" (1+ i))))
1297 ' > "${2}"
1299 ---Vassil.
1301 From: Decebal <cldwesterhof@gmail.com>
1302 Newsgroups: gnu.emacs.help
1303 Date: Sat, 10 Oct 2009 13:57:07 -0700 (PDT)
1304 To: help-gnu-emacs@gnu.org
1305 Envelope-To: andreas.roehler@easy-emacs.de
1307 On Oct 10, 10:06pm, Andreas R=F6hler <andreas.roeh...@easy-emacs.de>
1308 wrote:
1309 > > The Emacs batch gives output like:
1310 > > Saving file /home/cecil/temp/inputEmacs...
1312 > it's in files.el, save-buffer, AFAIS
1314 > (if (and modp (buffer-file-name))
1315 > (message "Saving file %s..." (buffer-file-name)))
1317 > commenting out these lines should cancel the message
1319 The problem with that is that it only works for me. But I found a way.
1320 I replaced:
1322 (write-file output-file))
1324 with:
1326 (set-visited-file-name output-file)
1327 (basic-save-buffer))
1329 But maybe there should be more consideration for the possibility that
1330 Emacs is used as a batch program.
1332 > > Wrote /home/cecil/temp/inputEmacs
1334 I still have to find something for this.
1336 That is not possible I am afraid. In the C-source there is a call to
1337 message_with_string.
1339 * vectors and lists
1341 From: pjb@informatimago.com (Pascal J. Bourguignon)
1342 Newsgroups: gnu.emacs.help
1343 Date: Fri, 09 Oct 2009 19:19:49 +0200
1344 To: help-gnu-emacs@gnu.org
1345 Envelope-To: andreas.roehler@easy-emacs.de
1347 Nordlöw <per.nordlow@gmail.com> writes:
1349 > If I have an association list say,
1351 > '(
1352 > ("key" sym1 val1 num1)
1353 > ("key2" sym2 val2 num2)
1356 > , where each entry is a fixed sequence of various objects.
1358 If this is an a-list, then you could write it as:
1360 (("key1" . (sym1 val1 num1))
1361 ("key2" . (sym2 val2 numb2)))
1363 to show that it is a list of cons cells.
1365 (a . (b c d)) <=> (a b c d), but the first notation shows that you
1366 consider it as a list of cons, and notably that you don't expect nil
1367 ie. () to be in the toplevel of the a-list.
1369 Also, if we write the a-list properly like this, we can better answer
1370 the following question:
1372 > I might
1373 > aswell use a vector to represent an entry in this alist, right?
1375 You cannot use a vector instead of the cons cells of the a-list, but
1376 you can use a vector as a value of an a-list entry. Values can be of
1377 any type. In the case of emacs lisp, you could also easily use
1378 vectors (or any other type) as keys in an a-list, since it uses equal
1379 to compare keys.
1381 (("key1" . [sym1 val1 num1])
1382 ("key2" . [sym2 val2 num2])
1383 ([?k ?e ?y ?3] . [sym3 val3 num3]))
1385 > In this case, what do I gain by using a vector instead of list?
1387 In general, vectors take half the space of lists, and access to the
1388 nth element is done in O(1) instead of O(n) with lists. However,
1389 adding or removing an element in a vector is O(n) while in the case of
1390 lists, it may be O(1) (prepending an element or removing the first
1391 element or one of the few firsts elements) or O(n) (inserting,
1392 appending an element or removing the nth element).
1394 > What about performance?: aref() faster than nth() only for large
1395 > vectors?
1397 aref has to compute a multiplication and a sum, before doing one
1398 memory load to get the element. In the case of emacs lisp, the
1399 multiplication is always by the same fixed factor AFAIK.
1401 nth has to do n memory loads to get the element.
1403 So indeed, aref will probably be faster than nth, even for indices as
1404 small as 1 or 0.
1406 > Is there vector-variant of assoc()?
1408 No. Unless you count hash-tables as a vector variant.
1410 > If not, why?
1412 Because there's no point. The advantage of using a list for a-list,
1413 apart from the historical simplicity, is that you can easily prepend
1414 the a-list with new associations, and therefore use the a-list in a
1415 purely functional way.
1417 (defun f (bindings)
1418 (let ((val (cdr (assoc 'x bindings))))
1419 (if (zerop val)
1420 (list val)
1421 (cons val (f (cons (cons 'x (1- val)) bindings))))))
1423 (let ((bindings '((y . 0) (x . 1))))
1424 (list (f (cons (cons 'x 2) bindings))
1425 (cdr (assoc 'x bindings))))
1426 ;; --> ((2 1 0) 1)
1428 Note: you could use (require 'cl) (acons key value a-list)
1429 instead of (cons (cons key value) a-list).
1431 > Has any one already written such a function?
1433 Not AFAIK, but you can write it. However, the semantics of assoc
1434 require a sequential search of the keys in the list, so there would be
1435 no gain. On the contrary, we would now have O(n) complexity to
1436 prepend a new entry to the a-vector.
1439 __Pascal Bourguignon__