home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #16 / NN_1992_16.iso / spool / comp / lang / lisp / 2121 < prev    next >
Encoding:
Text File  |  1992-07-27  |  3.0 KB  |  78 lines

  1. Newsgroups: comp.lang.lisp
  2. Path: sparky!uunet!darwin.sura.net!mips!sdd.hp.com!usc!elroy.jpl.nasa.gov!ufo!Aig.Jpl.Nasa.Gov!charest
  3. From: charest@Aig.Jpl.Nasa.Gov (Len Charest)
  4. Subject: Re: local macro definitions
  5. Message-ID: <1992Jul27.220158.28453@jpl-devvax.jpl.nasa.gov>
  6. Followup-To: comp.lang.lisp
  7. Sender: usenet@jpl-devvax.jpl.nasa.gov (For NNTP so rrn will be able to post)
  8. Nntp-Posting-Host: ai-cyclops
  9. Reply-To: charest@aig.jpl.nasa.gov
  10. Organization: NASA/Jet Propulsion Laboratory
  11. References:  <4133@inca.comlab.ox.ac.uk>
  12. Date: Mon, 27 Jul 1992 22:01:58 GMT
  13. Lines: 63
  14.  
  15. In article <4133@inca.comlab.ox.ac.uk>, gordon@robots.oxford.ac.uk (Gordon Buxton) writes:
  16. |>  What I would really
  17. |> like to do is to let the user refer to the other slot names in the
  18. |> frame as if they were locally bound variables:
  19.  
  20. All of the approaches suggested here imply that the list of frame slots
  21. is available at compile-time (really macroexpansion-time). Is this
  22. truly the case?
  23.  
  24. |> 
  25. |> 1. A list of all of the slots present in a frame is available; the
  26. |> user code calling sequence could bind each slot name to the value of
  27. |> the (val ..) function called for that slot.
  28. |> 
  29. |>     -- Inefficient to say the least.  In fact it gets more hideous
  30. |>        the more you think about it.
  31.  
  32. Why does is this intrinsically inefficent? You could hide the binding
  33. mechanism from the user code by wrapping the following code fragment
  34. around the user code:
  35.  
  36. (let ((slots <list of frame slots>))
  37.   (flet ((val-in-self (slot)
  38.        (val self slot))) 
  39.     ;;dynamically bind the slot names to values 
  40.     (progv slots (mapcar #'val-in-self slots)
  41.       ...<user code here>...
  42.       )))
  43.  
  44. The only (potential) drawback I can see is that calling VAL on each of
  45. the slots of the frame SELF is going to force execution of the user
  46. code in some cases (e.g, 'unbound' slots as you mentioned), possibly
  47. resulting in infinite recursion.
  48.  
  49. |> 2. Do some parsing on the user code, to work out which slots are
  50. |> needed, and just go and get them before executing the code.
  51. |> 
  52. |>     -- Doesn't strike me as a good idea.
  53.  
  54. This is a great idea! If you are certain that a slot name (i.e.,
  55. symbol) is really just a symbolic reference to the slot's value in this
  56. context then you could re-write the body of the user code so that every
  57. reference to a slot name is replaced by the corresponding (eq) value.
  58. For example
  59.  
  60. (flet ((insert-value (slot body)
  61.          (nsubst (val self slot) slot body :test #'eq)))
  62.   (let ((body (copy-tree <user code>)))
  63.     (loop for slot in <list of frame slots>
  64.           do (setq body (insert-value slot body)))
  65.     body))
  66.           
  67. You might even choose to 'optimize' other parts of the user code at
  68. this point.
  69.  
  70. |> 3. Bind each of the slot names to a macro (macrolet ... ?) that then
  71. |> gets expanded to (val self '<slot-name>) upon execution.
  72.  
  73. As barmar has already pointed out, the form to use is SYMBOL-MACROLET.
  74. ..................................................
  75.                                   Len Charest, Jr.
  76.                  JPL Artificial Intelligence Group
  77.                           charest@aig.jpl.nasa.gov
  78.