self-typing
[elbb.git] / code / elbb.el
blob9d41967f96b51fc3ee1bb64cfb8d4c92617323e6
1 * self-typing
3 From: pjb@informatimago.com (Pascal J. Bourguignon)
4 Date: Sat, 26 Dec 2009 14:32:16 +0100
5 To: help-gnu-emacs@gnu.org
6 Subject: Re: what is `self-typing' ?
8 waterloo <waterloo2005@gmail.com> writes:
10 > I can not understand a para in Elisp manual :
12 > Lisp is unlike many other languages in that its objects are
13 > "self-typing": the primitive type of each object is implicit in the
14 > object itself.  For example, if an object is a vector, nothing can
15 > treat it as a number; Lisp knows it is a vector, not a number.
17 > What is `self-typing' ? thanks
19 As mentionned by Eli. But this require some more explaination.
21 Some languages are defined so that variables can hold only objects of
22 a given type (you declare the type of the variable, or it is infered
23 automatically at compilation time). For example, C or Haskell.
25 Since all the types of the objects are known at compilation time from
26 the variables they're stored in, the compiler doesn't need to generate
27 code to store the type along with the object, or along with the
28 variable: the type is implicity. In C, typeof(42) or int a=42; typeof(a)
29 is computed at compilation time.
31 Some languages are defined so that variables can hold objects of
32 different types, at different times. In that case, the type is not
33 attached to the variable, but must be attached to the objects
34 themselves. For example, Lisp or Smalltalk.
36 Since it is rarely possible to know what type of object a variable
37 will hold (some type inference can still be applied to optimize out
38 some function, but there remains a lot of functions where type
39 inference doesn't restrict much the possible types, the more so when
40 global analysis is not practical or possible), then the type of each
41 object has to be kept with the object. In Lisp, (type-of 42) or (let
42 ((a 42)) (type-of 42)) is computed at run-time. Notably, you can
43 write: (type-of (read)) and depending on what you enter at run-time,
44 will get back one type or another:
46 M-x ielm RET
47 *** Welcome to IELM *** Type (describe-mode) for help.
48 ELISP> (type-of (read))
49 Lisp expression: 42
50 integer
51 ELISP> (type-of (read))
52 Lisp expression: "fourty-two"
53 string
54 ELISP> (type-of (read))
55 Lisp expression: fourty-two
56 symbol
57 ELISP> (type-of (read))
58 Lisp expression: (fourty two)
59 cons
60 ELISP>
62 There are also languages where both things are more or less possible,
63 you can have variables with pre-defined types holding only one type of
64 object, and variables which can hold objects of various types, but of
65 a same root class. For example, C++ or Java.
67 These languages usually provide so called "Plain Old Data" types which
68 correspond to the type of objects that can only be stored in variables
69 with predefined types. These objects of these POD types usually
70 don't have the type attached to them, these objects can only be stored
71 in variables with pre-defined type. When you want to store such an
72 object in a variable-type variable, you have to wrap it in another
73 object, a typed object, instance of a class. In Java, you have a POD
74 type int and an object class Integer.
76 --
77 __Pascal Bourguignon__ http://www.informatimago.com/
79 * Emacs uptime
81 From: pjb@informatimago.com (Pascal J. Bourguignon)
82 Date: Wed, 23 Dec 2009 20:16:03 +0100
83 To: help-gnu-emacs@gnu.org
84 Subject: Re: Some functions I hope are useful for others to
86 [ ... ]
88 For example, here is my emacs-uptime:
90 (defvar com.informatimago.time/*emacs-start-time* (current-time)
91 "For (emacs-uptime)")
93 (defun com.informatimago.time/emacs-uptime ()
94 "Gives Emacs' uptime, based on global var `com.informatimago.time/*emacs-start-time*'."
95 (interactive)
96 (let* ((st com.informatimago.time/*emacs-start-time*)
97 (cur (current-time))
98 (hi-diff (- (car cur) (car st)))
99 (tot-sec (+ (ash hi-diff 16) (- (cadr cur) (cadr st))))
100 (days (/ tot-sec (* 60 60 24)))
101 (hrs (/ (- tot-sec (* days 60 60 24)) (* 60 60)))
102 (mins (/ (- tot-sec (* days 60 60 24) (* hrs 60 60)) 60))
103 (secs (/ (- tot-sec (* days 60 60 24) (* hrs 60 60) (* mins 60)) 1)))
104 (message "Up %dd %dh %dm %ds (%s), %d buffers, %d files"
105 days hrs mins secs
106 (format-time-string "%a %Y-%m-%d %T" st)
107 (length (buffer-list))
108 (count t (buffer-list)
109 :test-not
110 (lambda (ignore buf)
111 (null (cdr (assoc 'buffer-file-truename
112 (buffer-local-variables buf)))))))))
114 (defalias 'emacs-uptime 'com.informatimago.time/emacs-uptime)
116 [ .... ]
118 * Using Emacs Lisp for script writing
120 To: help-gnu-emacs@gnu.org
121 From: David Engster <deng@randomsample.de>
122 Date: Sat, 19 Dec 2009 11:02:22 +0100
123 Subject: Re: Using Emacs Lisp for script writing
125 Andreas Politz <politza@fh-trier.de> writes:
126 > Cecil Westerhof <Cecil@decebal.nl> writes:
128 >> I already use 'emacs -batch' for scripting where no user input is used,
129 >> but I would like to use it also for interactive scripting. Until now I
130 >> did not find any usable information about this. Anybody using Emacs for
131 >> interactive scripts?
133 > No, but it should be noted, that this is not very difficult :
135 > $ emacs -Q -batch -eval '(yes-or-no-p "Want some cookies ?")'
137 You can also use the '--script' option in a shebang line:
139 ----------------- test.sh -----------------
140 #!/usr/bin/emacs --script
142 (if (yes-or-no-p "Choose ")
143 (message "You said yes")
144 (message "You said no"))
145 -------------------------------------------
147 I use emacs regularly for writing scripts, since with its thousands of
148 packages you have a huge library readily available.
150 -David
152 * favourite directories implementation
154 Author: Florent Georges, source:
155 http://fgeorges.blogspot.com/2008/01/emacs-favourite-directories.html
157 Today, I have finally taken a look at one of the
158 simple features I always missed in Emacs: the
159 ability to define a set of "favourite directories."
160 That is, a set of named directories that one can use
161 in the minibuffer when prompted for instance to open
162 a file. Given a set of such dirs:
164 emacs-src -> /enter/your/path/to/emacs/sources
165 projects -> /path/to/some/company/projects
166 now -> @projects/the/project/I/am/working/on
168 one can use the following path in the minibuffer to open a file,
169 for instance using C-x C-f:
171 @emacs-src/lisp/files.el
172 @emacs-src/src/alloc.c
173 @projects/great/README
174 @now/src/some/stuff.txt
176 Doing so, completion is available for both directory names and
177 files under their target directories. For instance, to open the
178 third file above, you only have to type:
180 C-x C-f @ p <tab> g <tab> R <tab> <enter>
182 The implementation I have just written is really simple, but
183 useful yet. It implements all described above (including
184 recursive defined directories, as the '@now' above.) Thanks to
185 Emacs, I am still suprised by the facility to implement such a
186 feature!
188 The code was written on GNU Emacs 22.1 on Windows, but should
189 work on any platform, and I think on Emacs 21 as well.
191 TODO: Make a custom variable.
192 (defvar drkm-fav:favourite-directories-alist
193 '(("saxon-src" . "y:/Saxon/saxon-resources9-0-0-1/source/net/sf/saxon")
194 ("kernow-src" . "~/xslt/kernow/svn-2007-09-29/kernow/trunk/src/net/sf/kernow"))
195 "See `drkm-fav:handler'.")
197 (defvar drkm-fav::fav-dirs-re
198 ;; TODO: Is tehre really no other way (than mapcar) to get the list
199 ;; of the keys of an alist?!?
200 (concat
201 "^@"
202 (regexp-opt
203 (mapcar 'car drkm-fav:favourite-directories-alist)
205 "Internal variable that stores a regex computed from
206 `drkm-fav:favourite-directories-alist'. WARNING: This is not
207 updated automatically if the later variable is changed.")
209 (defun drkm-fav:handler (primitive &rest args)
210 "Magic handler for favourite directories.
212 With this handler installed into `file-name-handler-alist', it is
213 possible to use shortcuts for often used directories. It uses
214 the mapping in the alist `drkm-fav:favourite-directories-alist'.
216 Once installed, say you have the following alist in the mapping
217 variable:
219 ((\"dir-1\" . \"~/some/real/dir\")
220 (\"dir-2\" . \"c:/other/dir/for/windows/users\"))
222 You can now use \"@dir-1\" while opening a file with C-x C-f for
223 instance, with completion for the abbreviation names themselves
224 as well as for files under the target directory."
225 (cond
226 ;; expand-file-name
227 ((and (eq primitive 'expand-file-name)
228 (string-match drkm-fav::fav-dirs-re (car args)))
229 (replace-match
230 (cdr (assoc (match-string 1 (car args))
231 drkm-fav:favourite-directories-alist))
232 t t (car args)))
233 ;; file-name-completion
234 ((and (eq primitive 'file-name-completion)
235 (string-match "^@\\([^/]*\\)$" (car args)))
236 (let ((compl (try-completion
237 (match-string 1 (car args))
238 drkm-fav:favourite-directories-alist)))
239 (cond ((eq t compl)
240 (concat "@" (match-string 1 (car args)) "/"))
241 ((not compl)
242 nil)
244 (concat "@" compl)))))
245 ;; file-name-all-completions
246 ((and (eq primitive 'file-name-all-completions)
247 (string-match "^@\\([^/]*\\)$" (car args)))
248 (all-completions
249 (match-string 1 (car args))
250 drkm-fav:favourite-directories-alist))
251 ;; Handle any primitive we don't know about (from the info node
252 ;; (info "(elisp)Magic File Names")).
253 (t (let ((inhibit-file-name-handlers
254 (cons 'drkm-fav:handler
255 (and (eq inhibit-file-name-operation primitive)
256 inhibit-file-name-handlers)))
257 (inhibit-file-name-operation primitive))
258 (apply primitive args)))))
260 ;; Actually plug the feature into Emacs.
261 (push '("\\`@" . drkm-fav:handler) file-name-handler-alist)
263 * lisp interface to ispell
265 From: Teemu Likonen <tlikonen@iki.fi>
266 Date: Fri, 06 Nov 2009 22:05:53 +0200
267 To: help-gnu-emacs@gnu.org
268 Subject: Re: lisp interface to ispell ?
270 On 2009-11-06 20:39 (+0100), Andreas Politz wrote:
272 > Does someone have a hack, or know a different package, in order to allow
273 > elisp access to spelling functions ? E.g. like
275 > (spell word language)
277 > which at least returns t or nil.
279 Something like this?
281 (defun my-ispell-string (word lang)
282 (with-temp-buffer
283 (insert word)
284 (call-process-region (point-min) (point-max)
285 "ispell" t t nil "-l" "-d" lang)
286 (if (= (point-min) (point-max))
287 t)))
289 * Python workflow
291 From: Simon <bbbscarter@gmail.com>
292 Date: Fri, 6 Nov 2009 03:42:44 -0800 (PST)
293 To: help-gnu-emacs@gnu.org
294 Subject: Python workflow
296 Hi, apologies in advance for a potentially numpty post.
298 I've been using Emacs for a little while now, but I've yet to settle
299 on a satisfactory python edit-run-debug cycle, and I was wondering
300 what wiser minds than mine have settled upon. So far I've tried:
302 - Edit code and run with emacs PDB. After fiddling the lisp code to
303 automatically pick up the current buffer as the default run candidate,
304 this is nearly okay. The main issue is that, after editing code,
305 there's no easy way to rerun the code, so I end up killing the gud
306 buffer every time. As such, entering and leaving the debugger is quite
307 a few key presses and accidentally leaving it running is also easy.
309 - Tried Pydb to similar effect.
311 - Run everything in a seperate shell. And debug by hand. This is a
312 little too low-fi, even for me.
314 - Use the 'import/reload file' and 'eval def/class' functions, and run
315 everything from the emacs python shell, using pdbtrack to help with
316 debugging. Problems so far:
317 - It's very easy to forget which modules you've modified and fail to
318 reload them; because the state is carried over I continually find
319 myself running the old versions of code I've just edited, especially
320 if it's across several files.
321 - More than that, sometimes the stuff I expect to reload simply
322 doesn't, and I have no indication as to why. For example, if pdb has
323 module open and you stick a deliberate error in the code and reload
324 it, the minibuffer tells you the module has been loaded, even though
325 it clearly can't have been.
326 - I have to run pdb.pm() to debug the exception. If I run *anything*
327 else by accident, I lose the exception context. This can be annoying
328 if you're incompetent enough to keep making typos (I am).
330 Does anyone have any tips on their workflow?
332 Many thanks!
334 Simon
336 * strip out UTF-8 BOMs
337 From: "Edward O'Connor" <hober0@gmail.com>
338 Date: Thu, 5 Nov 2009 16:13:27 -0800
339 To: emacs-devel@gnu.org
340 Subject: find-file-literally-at-point
344 I recently found myself in need of such a function (I was going through
345 a bunch of files to strip out their UTF-8 BOMs, if you're curious), and
346 it was quick enough to put together:
348 (autoload 'ffap-guesser "ffap")
349 (defun find-file-literally-at-point ()
350 "Open the file at point (like `ffap') with `find-file-literally'."
351 (interactive)
352 (find-file-literally (ffap-guesser)))
354 * xml and n3
356 From: "Eric Schulte" <schulte.eric@gmail.com>
357 Subject: Re: [Orgmode] org-babel-tangle xml text
358 Date: Tue, 03 Nov 2009 09:18:34 -0700
360 "Martin G. Skjæveland" <martige@ifi.uio.no> writes:
362 > Is there a way I can add xml and n3 to the list of supported
363 > languages? These languages does not need interpretation, so I'm
364 > thinking it should be quite easy to add. I have fumblingly tried
366 > (add-to-list 'org-babel-tangle-langs '("xml"))
368 > and
370 > (add-to-list 'org-babel-tangle-langs '("css" "xml"))
372 > but it as no effect.
375 Hi Martin,
377 The attached org-mode file contains instructions for adding xml and n3
378 to org-babel and org-babel-tangle. Note that there may be another step
379 if the major mode for n3 is not n3-mode. Best -- Eric
381 introduce org-babel to =xml= and =n3=
383 #+begin_src emacs-lisp :results silent
384 (org-babel-add-interpreter "xml")
385 (org-babel-add-interpreter "n3")
386 #+end_src
388 if say =n3= should be edited using =xml-mode=, then evaluate the
389 following adding this pair to =org-src-lang-modes=
391 #+begin_src emacs-lisp :results silent
392 (add-to-list 'org-src-lang-modes '("n3" . xml))
393 #+end_src
395 ;; inform org-babel-tangle of their existence and file extensions
396 #+begin_src emacs-lisp :results silent
397 (add-to-list 'org-babel-tangle-langs '("xml" "xml" nil t))
398 (add-to-list 'org-babel-tangle-langs '("n3" "n3" nil t))
399 #+end_src
401 #+begin_src xml :tangle example
402 <first>
403 </first>
404 #+end_src
406 #+begin_src n3 :tangle example
407 n3 stuff
408 #+end_src
410 * How to check regexp for syntax-errors?
412 From: Kevin Rodgers <kevin.d.rodgers@gmail.com>
413 Date: Tue, 20 Oct 2009 01:54:56 -0600
414 Subject: Re: How to check regexp for syntax-errors?
415 David Combs wrote:
416 > Isn't there some .el that that will try to parse a regexp, and tell
417 > me where it got confused, and what to look for for errors?
419 (defun valid-regexp-p (regexp)
420 (interactive "sRegexp: ")
421 (with-temp-buffer
422 (condition-case error-data
423 (progn
424 (re-search-forward regexp nil t)
426 (invalid-regexp
427 (when (interactive-p) (message "Invalid regexp: %s" (cdr error-data)))
428 nil))))
431 Kevin Rodgers
432 Denver, Colorado, USA
434 * prefer cond over case?
436 From: David Kastrup <dak@gnu.org>
437 Date: Mon, 12 Oct 2009 10:03:39 +0200
438 To: help-gnu-emacs@gnu.org
439 Subject: Re: Perferr cond over case?
441 pjb@informatimago.com (Pascal J. Bourguignon) writes:
443 > Nordlöw <per.nordlow@gmail.com> writes:
445 >> Does the use of the cl macro case() incurr some loss of performance
446 >> compare to using cond() instead?
448 > (macroexpand '(case (* 2 2 2 2 3)
449 > (10 'one)
450 > ((24 42) 'two)
451 > ((3 33) 'three)
452 > (otherwise 'unknown)))
453 > -->
454 > (let ((--cl-var-- (* 2 2 2 2 3)))
455 > (cond ((eql --cl-var-- (quote 10)) (quote one))
456 > ((member* --cl-var-- (quote (24 42))) (quote two))
457 > ((member* --cl-var-- (quote (3 33))) (quote three))
458 > (t (quote unknown))))
460 > What do you think?
462 Before or after byte compilation?
465 David Kastrup
467 * batch-mode
469 From: Decebal <cldwesterhof@gmail.com>
470 Newsgroups: gnu.emacs.help
471 Date: Sat, 10 Oct 2009 11:33:17 -0700 (PDT)
472 To: help-gnu-emacs@gnu.org
473 Envelope-To: andreas.roehler@easy-emacs.de
475 In a Bash script I changed:
477 local i
478 local length=${#1}
480 for i in $(seq ${1}) ; do
481 printf " Regel %${length}d voor de test\n" ${i}
482 done >${2}
485 emacs -batch -nw --eval='
486 (let (
488 (nr-of-lines '${1}')
489 (nr-of-lines-length)
490 (output-file "'"${2}"'"))
491 (setq nr-of-lines-length (length (number-to-string nr-of-lines)))
492 (dotimes (i nr-of-lines t)
493 (insert (format (format " Regel %%%dd voor de test\n" nr-of-lines-length) (1+ i))))
494 (write-file output-file))
495 ' 2>/dev/null
497 The Bash version took 293 seconds and the Emacs Lisp version 59
498 seconds. So it is about 5 times as fast.
499 The Emacs batch gives output like:
500 Saving file /home/cecil/temp/inputEmacs...
501 Wrote /home/cecil/temp/inputEmacs
502 That is why I use the 2>/dev/null.
503 Is there a way to circumvent the generation of the above output?
504 Because when there is an error it is also thrown away and that is not
505 nice.
507 From: Vassil Nikolov <vnikolov@pobox.com>
508 Newsgroups: gnu.emacs.help
509 Date: Sat, 10 Oct 2009 16:55:31 -0400
510 To: help-gnu-emacs@gnu.org
511 Envelope-To: andreas.roehler@easy-emacs.de
513 On Sat, 10 Oct 2009 11:33:17 -0700 (PDT), Decebal <cldwesterhof@gmail.com> said:
514 > ...
515 > local i
516 > local length=${#1}
517 > for i in $(seq ${1}) ; do
518 > printf " Regel %${length}d voor de test\n" ${i}
519 > done >${2}
521 translates to
523 emacs -Q -batch -eval '
524 (dotimes (i '"${1}"')
525 (princ (format " Regel %'"${#1}"'d voor de test\n" (1+ i))))
526 ' > "${2}"
528 ---Vassil.
530 From: Decebal <cldwesterhof@gmail.com>
531 Newsgroups: gnu.emacs.help
532 Date: Sat, 10 Oct 2009 13:57:07 -0700 (PDT)
533 To: help-gnu-emacs@gnu.org
534 Envelope-To: andreas.roehler@easy-emacs.de
536 On Oct 10, 10:06pm, Andreas R=F6hler <andreas.roeh...@easy-emacs.de>
537 wrote:
538 > > The Emacs batch gives output like:
539 > > Saving file /home/cecil/temp/inputEmacs...
541 > it's in files.el, save-buffer, AFAIS
543 > (if (and modp (buffer-file-name))
544 > (message "Saving file %s..." (buffer-file-name)))
546 > commenting out these lines should cancel the message
548 The problem with that is that it only works for me. But I found a way.
549 I replaced:
551 (write-file output-file))
553 with:
555 (set-visited-file-name output-file)
556 (basic-save-buffer))
558 But maybe there should be more consideration for the possibility that
559 Emacs is used as a batch program.
561 > > Wrote /home/cecil/temp/inputEmacs
563 I still have to find something for this.
565 That is not possible I am afraid. In the C-source there is a call to
566 message_with_string.
568 * vectors and lists
570 From: pjb@informatimago.com (Pascal J. Bourguignon)
571 Newsgroups: gnu.emacs.help
572 Date: Fri, 09 Oct 2009 19:19:49 +0200
573 To: help-gnu-emacs@gnu.org
574 Envelope-To: andreas.roehler@easy-emacs.de
576 Nordlöw <per.nordlow@gmail.com> writes:
578 > If I have an association list say,
580 > '(
581 > ("key" sym1 val1 num1)
582 > ("key2" sym2 val2 num2)
585 > , where each entry is a fixed sequence of various objects.
587 If this is an a-list, then you could write it as:
589 (("key1" . (sym1 val1 num1))
590 ("key2" . (sym2 val2 numb2)))
592 to show that it is a list of cons cells.
594 (a . (b c d)) <=> (a b c d), but the first notation shows that you
595 consider it as a list of cons, and notably that you don't expect nil
596 ie. () to be in the toplevel of the a-list.
598 Also, if we write the a-list properly like this, we can better answer
599 the following question:
601 > I might
602 > aswell use a vector to represent an entry in this alist, right?
604 You cannot use a vector instead of the cons cells of the a-list, but
605 you can use a vector as a value of an a-list entry. Values can be of
606 any type. In the case of emacs lisp, you could also easily use
607 vectors (or any other type) as keys in an a-list, since it uses equal
608 to compare keys.
610 (("key1" . [sym1 val1 num1])
611 ("key2" . [sym2 val2 num2])
612 ([?k ?e ?y ?3] . [sym3 val3 num3]))
614 > In this case, what do I gain by using a vector instead of list?
616 In general, vectors take half the space of lists, and access to the
617 nth element is done in O(1) instead of O(n) with lists. However,
618 adding or removing an element in a vector is O(n) while in the case of
619 lists, it may be O(1) (prepending an element or removing the first
620 element or one of the few firsts elements) or O(n) (inserting,
621 appending an element or removing the nth element).
623 > What about performance?: aref() faster than nth() only for large
624 > vectors?
626 aref has to compute a multiplication and a sum, before doing one
627 memory load to get the element. In the case of emacs lisp, the
628 multiplication is always by the same fixed factor AFAIK.
630 nth has to do n memory loads to get the element.
632 So indeed, aref will probably be faster than nth, even for indices as
633 small as 1 or 0.
635 > Is there vector-variant of assoc()?
637 No. Unless you count hash-tables as a vector variant.
639 > If not, why?
641 Because there's no point. The advantage of using a list for a-list,
642 apart from the historical simplicity, is that you can easily prepend
643 the a-list with new associations, and therefore use the a-list in a
644 purely functional way.
646 (defun f (bindings)
647 (let ((val (cdr (assoc 'x bindings))))
648 (if (zerop val)
649 (list val)
650 (cons val (f (cons (cons 'x (1- val)) bindings))))))
652 (let ((bindings '((y . 0) (x . 1))))
653 (list (f (cons (cons 'x 2) bindings))
654 (cdr (assoc 'x bindings))))
655 ;; --> ((2 1 0) 1)
657 Note: you could use (require 'cl) (acons key value a-list)
658 instead of (cons (cons key value) a-list).
660 > Has any one already written such a function?
662 Not AFAIK, but you can write it. However, the semantics of assoc
663 require a sequential search of the keys in the list, so there would be
664 no gain. On the contrary, we would now have O(n) complexity to
665 prepend a new entry to the a-vector.
668 __Pascal Bourguignon__