Path: utzoo!mnetor!uunet!lll-winken!lll-lcc!rutgers!clyde!burl!codas!mtune!whuts!davel From: davel@whuts.UUCP (David Loewenstern) Newsgroups: comp.lang.lisp Subject: Re: A CL iteration macro, "while". Message-ID: <3503@whuts.UUCP> Date: 30 Dec 87 21:31:34 GMT References: <13639@beta.UUCP> Organization: AT&T Bell Laboratories Lines: 72 Keywords: Let's have a little non-flamable fun... In article <13639@beta.UUCP>, dzzr@beta.UUCP (Douglas J Roberts) writes: > > I was poking around in the source for Stallman's Gnu Emacs the other day > and stumbled across a "while" function that I kind of liked. It's not > Common nor Zeta LISP, and so I'd never seen it before. We have > Symbolic's big loop macro installed on all of our Common LISP machines > (Suns, TI Explorers, & Symbolics), but even with it there is no clean > way to do simple iteration control that I really like. (I don't like the > syntax of do, dotimes, dolist, etc.) I certainly don't blame you. DOTIMES and DOLIST don't bother me, but DO is REALLY ugly -- not much better than using PROG. > > I thought it would be fun to write a CL while macro and then post it > for comment, etc. I'd be curious for anybody interested enough to > suggest other ways of writing it. > > Here 'tis. > > > (defmacro while (test-form &rest forms) > "This macro evaluates test-form, and if the result is non-nil > all subsequent forms will be iteratively evaluated until > test-form evaluates to nil." > (prog () > again > (cond ( > (eval test-form) > (mapcar #'eval forms) > (go again) > )) > )) This macro performs the loop on expansion. It cannot be usefully compiled, since it always expands to NIL. Try calling the following function *twice*: (DEFUN X (n) (WHILE (PLUSP n) (WHEN (ODDP n) (PRINT n)) (DECF n))) I predict: typing (X 5) will print 5 3 1 NIL and typing (X 5) again will print NIL certainly this is the standard behavior on the Symbolics and Explorers. What is wrong with (LOOP while (< *number* 5) do (print *number*) ... (setq *number* (1+ *number*))) ? In any event, what you probably meant was (DEFMACRO While (test &BODY body) `(PROG () AGAIN (WHEN ,test ,@body (GO AGAIN)))) except that this doesn't do anything more than the LOOP macro which you already have. > Doug Roberts > dzzr@lanl.gov -- David Loewenstern Bangpath: {rutgers!moss,ihnp4}!whuts!davel or -- in extremis -- loewenst@paul.rutgers.edu Disclaimer: My opinions are controlled by the Bavarian Illuminati, not by AT&T.