Stoppt die Vorratsdatenspeicherung! Jetzt klicken &handeln! Willst du auch an der Aktion teilnehmen? Hier findest du alle relevanten Infos
  und Materialien:

Skip to content


Lisp macros revisited

Since my first posts on my own little control macros (while, foreach etc.) I’ve learned quite a bit and so here are my revised versions of some of them, since not all of them would work outside of an interpreter, since they were recursive macros.
A better, and also non recursive way to write macros is to either use exisiting macros (as done with my for macro) or for example by using the tagbody & go constructs of lisp (similar to a goto in C):

new while macro

1
2
3
4
5
6
7
8
;; while macro with tagbody & go.
(defmacro while-new (condition &body body)
  (let ((tag-name (gensym)))
    `(tagbody
      ,tag-name
      ,@body
      (when ,condition
	(go ,tag-name)))))

Thanks again to the anonymous commenter ‘foo’, who made it clear, that the previous version (without gensymed-symbols) could make trouble in the case of a caller having symbols defined with the same name (in this case tag-name).

I also changed the foreach-macro to use gensymed symbols:

new foreach macro

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
;; foreach macro with tagbody & go.
(defmacro foreach-new ((var list) &body body)
  (let ((tmp-list (gensym)) (start-tag (gensym)))
    `(let* ((,tmp-list ,list) (,var nil) (rest (cdr ,tmp-list)))
       (tagbody
	  ,start-tag
	  (if (null ,tmp-list)
	      nil
	      (progn
		(setf ,var (car ,tmp-list))
		(setf rest (cdr ,tmp-list))
		(if ,var
		  (progn ,@body
			 (setf ,tmp-list rest)
			 (go ,start-tag))
		  nil)))))))

new until macro

1
2
3
4
;; until macro reusing new while macro.
(defmacro until-new (cond &body body)
  `(while-new (not ,cond)
     ,@body))

Also, thanks to ‘foo’, who pointed this out in some comments.
I’ve known about this fact for little while already, but haven’t thought about posting it here. Since some people might be reading this and wondering, why they don’t seem to work, they now should have some working samples.

Posted in General. Tagged with , , , , , .

One Response

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.

  1. foo said

    TOP, TMP and START interfere with user code. The user might also want to use those symbols.

    Destructuring like that won’t work. Think of a list: (nil nil nil).
    CAR of that list is nil. The usual way to write recursion is (if (null list) (end-clause) (let ((element (first list)) (rest (rest list))) …).

    Also think if you really want to rebind the foreach variable in each iteration?

Some HTML is OK

(required)

(required, but never shared)

or, reply to this post via trackback.


Ihr Browser versucht gerade eine Seite aus dem sogenannten Internet auszudrucken. Das Internet ist ein weltweites Netzwerk von Computern, das den Menschen ganz neue Möglichkeiten der Kommunikation bietet.

Da Politiker im Regelfall von neuen Dingen nichts verstehen, halten wir es für notwendig, sie davor zu schützen. Dies ist im beidseitigen Interesse, da unnötige Angstzustände bei Ihnen verhindert werden, ebenso wie es uns vor profilierungs- und machtsüchtigen Politikern schützt.

Sollten Sie der Meinung sein, dass Sie diese Internetseite dennoch sehen sollten, so können Sie jederzeit durch normalen Gebrauch eines Internetbrowsers darauf zugreifen. Dazu sind aber minimale Computerkenntnisse erforderlich. Sollten Sie diese nicht haben, vergessen Sie einfach dieses Internet und lassen uns in Ruhe.

Die Umgehung dieser Ausdrucksperre ist nach §95a UrhG verboten.

Mehr Informationen unter www.politiker-stopp.de.