home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!olivea!apple!cambridge.apple.com!bill@cambridge.apple.com
- From: bill@cambridge.apple.com (Bill St. Clair)
- Newsgroups: comp.lang.lisp.mcl
- Subject: Re: Apply
- Message-ID: <9208121537.AA03113@cambridge.apple.com>
- Date: 12 Aug 92 16:40:11 GMT
- Sender: info-mcl-request@cambridge.apple.com
- Lines: 48
- Approved: comp.lang.lisp.mcl@Cambridge.Apple.C0M
- Full-Name: Bill St. Clair
- Original-To: Denis R Howlett <drh@world.std.com>
- Original-Cc: info-mcl
-
- >I too discovered that apply and funcall don't work for lambda lists any
- >more and was rather disheartened since a great deal of our user interface
- >code relies on constructing functions which are then attached to buttons.
- >
- >Much of this code is created with backquotes so that variables can be
- >insterted, a simple example might be:
- >
- >(defun make-menu-items (items)
- > (let (menu-items)
- > (dolist (item items)
- > (push (make-instance ...
- > :attached-function
- > `(lambda (window)
- > (declare (ignore window))
- > (print ',item)))))))
- >
- >I know the code isn't quite right but you get the idea, each lambda
- >expression is created at run time.
- >
- >The solution I have adopted (but don't like) is to make the function
- >dispatcher more intelligent and do the following:
- >
- >;; attached-function & window are bound in preceding lines
- > (funcall (if (listp attached-function)
- > (eval `(function ,attached-function))
- > attached-function)
- > window)
- >
- >This allows my dispatcher to deal with all the things that funcall (and
- >apply used to deal with), but I always thought it was bad form to use eval
- >in the middle of code? ...
-
- It IS bad form to use EVAL. You should realize that by saying
- (apply '(lambda (...) ...) ...), you were implicitly calling EVAL
- (or COMPILE). Closures will often solve your problem:
-
- (defun make-menu-items (items)
- (let (menu-items)
- (dolist (item items)
- (push (make-instance ...
- :attached-function
- #'(lambda (window)
- (declare (ignore window))
- (print item)))
- menu-items)
- ...)))
-
- Then you can leave your dispatching code as (funcall attached-function window).
-