home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #18 / NN_1992_18.iso / spool / comp / lang / lisp / mcl / 1193 < prev    next >
Encoding:
Text File  |  1992-08-12  |  2.2 KB  |  62 lines

  1. Path: sparky!uunet!olivea!apple!cambridge.apple.com!bill@cambridge.apple.com
  2. From: bill@cambridge.apple.com (Bill St. Clair)
  3. Newsgroups: comp.lang.lisp.mcl
  4. Subject: Re: Apply
  5. Message-ID: <9208121537.AA03113@cambridge.apple.com>
  6. Date: 12 Aug 92 16:40:11 GMT
  7. Sender: info-mcl-request@cambridge.apple.com
  8. Lines: 48
  9. Approved: comp.lang.lisp.mcl@Cambridge.Apple.C0M
  10. Full-Name: Bill St. Clair
  11. Original-To: Denis R Howlett <drh@world.std.com>
  12. Original-Cc: info-mcl
  13.  
  14. >I too discovered that apply and funcall don't work for lambda lists any
  15. >more and was rather disheartened since a great deal of our user interface
  16. >code relies on constructing functions which are then attached to buttons.
  17. >
  18. >Much of this code is created with backquotes so that variables can be
  19. >insterted, a simple example might be:
  20. >
  21. >(defun make-menu-items (items)
  22. >  (let (menu-items)
  23. >    (dolist (item items)
  24. >      (push (make-instance ...
  25. >                           :attached-function
  26. >                           `(lambda (window)
  27. >                  (declare (ignore window))
  28. >                              (print ',item)))))))
  29. >
  30. >I know the code isn't quite right but you get the idea, each lambda
  31. >expression is created at run time.
  32. >
  33. >The solution I have adopted (but don't like) is to make the function
  34. >dispatcher more intelligent and do the following:
  35. >
  36. >;; attached-function & window are bound in preceding lines
  37. >  (funcall (if (listp attached-function)
  38. >              (eval `(function ,attached-function))
  39. >              attached-function)
  40. >           window)
  41. >
  42. >This allows my dispatcher to deal with all the things that funcall (and
  43. >apply used to deal with), but I always thought it was bad form to use eval
  44. >in the middle of code? ...
  45.  
  46. It IS bad form to use EVAL. You should realize that by saying
  47. (apply '(lambda (...) ...) ...), you were implicitly calling EVAL
  48. (or COMPILE). Closures will often solve your problem:
  49.  
  50. (defun make-menu-items (items)
  51.   (let (menu-items)
  52.     (dolist (item items)
  53.       (push (make-instance ...
  54.               :attached-function
  55.               #'(lambda (window)
  56.                   (declare (ignore window))
  57.                   (print item)))
  58.             menu-items)
  59.       ...)))
  60.  
  61. Then you can leave your dispatching code as (funcall attached-function window).
  62.