home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #19 / NN_1992_19.iso / spool / comp / lang / lisp / 2343 < prev    next >
Encoding:
Text File  |  1992-08-31  |  2.4 KB  |  67 lines

  1. Path: sparky!uunet!mcsun!uknet!edcastle!aiai!jeff
  2. From: jeff@aiai.ed.ac.uk (Jeff Dalton)
  3. Newsgroups: comp.lang.lisp
  4. Subject: static, a.k.a. eval-once
  5. Message-ID: <7399@skye.ed.ac.uk>
  6. Date: 31 Aug 92 18:46:19 GMT
  7. Sender: news@aiai.ed.ac.uk
  8. Organization: AIAI, University of Edinburgh, Scotland
  9. Lines: 56
  10.  
  11. About 4 years ago, I wrote an EVAL-ONCE macro.  It appears, with
  12. an explanation below.  It has been claimed that my macro isn't
  13. portable because the behavior of gensyms isn't sufficiently
  14. restricted when compile and load is involved.  What I want to
  15. know is:
  16.  
  17.   1. Is there a problem with using GENSYM this way?
  18.  
  19.   2. Is there a better way to get what I want.
  20.  
  21.   3. Is there a way that will get the EVAL-ONCE effect in
  22.      interpreted code even in an "expand macros each time"
  23.      implementation?  (N.B. There is no correct portable way
  24.      to use *macroexpand-hook* cache macro expansions --
  25.      see page 204 of CLtL II.)
  26.  
  27. The "better way" will almost certainly involve LOAD-TIME-VALUE.
  28. But note that simply using LOAD-TIME-VALUE instead of EVAL-ONCE
  29. is not enough, because it might be that the form can't be evaluated
  30. at load time.  Using LOAD-TIME-VALUE to create a "cell" that
  31. can be modified to contain the desired value looks like the best
  32. possibility.
  33.  
  34. For the interpreted code problem, I can't think of anything better
  35. than having EVAL-ONCE assume that EQ forms are never logically
  36. different expressions.
  37.  
  38. Anyway, here is my old code:
  39.  
  40. ----------------------------------------------------------------------
  41. ;;; Oh, let us try this dubious trick...
  42. ;;; What we want is sort of like 'static'...
  43. ;;; Some code appears once but is executed again and again.
  44. ;;; Some value is computed each time the code is executed, but
  45. ;;; we would like it to be computed once and reused thereafter.
  46. ;;; (The value can't be computed at compile or load time, perhaps.)
  47. ;;; Each time this macro appears (modulo re-expansions), it
  48. ;;; creates a symbol that is ubound the first time the code
  49. ;;; is executed and has the desired value thereafter.
  50.  
  51. (defmacro eval-once (form)
  52.   `(let ((v ',(gensym)))        ;the symbol persists between calls
  53.      (if (boundp v)
  54.      (symbol-value v)
  55.        (set v ,form))))
  56.  
  57. #+maybe
  58. (defmacro eval-once (form)
  59.   (let ((v (gensym)))
  60.     `(locally (declare (special ,v))
  61.        (if (boundp ',v)
  62.            ,v
  63.          (setq ,v ,form)))))
  64. ----------------------------------------------------------------------
  65.  
  66. -- jd
  67.