home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!gatech!asuvax!farallon!danny.farallon.com!user
- From: danny@farallon.com (Danny Brewer)
- Newsgroups: comp.lang.lisp
- Subject: Re: Can I use EVAL?
- Message-ID: <danny-280892103325@danny.farallon.com>
- Date: 28 Aug 92 16:05:17 GMT
- References: <danny-250892143222@danny.farallon.com> <MOORE.92Aug25153642@defmacro.cs.utah.edu>
- Sender: news@farallon.farallon.com
- Followup-To: comp.lang.lisp
- Organization: Farallon Computing, Inc.
- Lines: 90
- Nntp-Posting-Host: danny
-
- Thanks to everyone who responded with postings or email.
-
- The solution I liked best was (COMPILE NIL *p*) to produce a
- function that can be FUNCALLed.
-
- I could see from several emails that I should have been more
- clear in my original posting about the fact that I cannot
- simply put #' in front of a LAMBDA in the pattern compiler
- and return a closure. There is no LAMBDA embedded within
- the compiler that is returned. The returned LAMBDA list
- is actually "computed" from the pattern and can vary
- greatly due to the fact that the matchers support nested
- patterns, anonymous variables, segment matching and pattern
- directives.
-
- Since I got such a satisfying solution to my first ugly EVAL,
- here's another place I've used EVAL and wonder if there is
- an alternative. (Note all of the following discussion applies
- to the interpretive matcher, the compiling matcher simply compiles
- function names or LAMBDAs into the resulting LAMBDA expression.
- The interpretive matcher EVAL's them.)
-
- The pattern directives can contain predicates. For example:
-
- (Match '(a (?:* ?x) (?:? ?n NUMBERP) (?:* ?y) (?:+ ?z SUBSETP '(a b c)))
- '(a b c d 5 e f g a b a c b))
-
- which results in the bindings:
-
- ((?Z A B A C B) (?Y E F G) (?N . 5) (?X B C D))
-
- The pattern means:
- Match an 'a
- followed by zero or more items,
- followed by a number,
- followed by zero or more items,
- followed by one or more items, all of which must be SUBSETP of '(a b c)
-
- Other pattern directive examples would be:
-
- (?:? ?x > 5)
- (?:@ ?_ CONSP)
- (?:? ?str STRINGP)
- (?:? ?n = *PRINT-BASE*)
- (?:* ?items (LAMBDA (items) (SUBSETP (INTERSECTION items *x*) *y*)))
-
- The last example would match some items which when intersected with
- the special variable *x* are a subset of special variable *y*.
-
- Basically, the third item can be the name of a function (or LAMBDA),
- and additional arguments can be given, such as the > function being
- given the argument 5 to test if ?x > 5 in the first example.
-
- I use the following function to see if the pattern directive can
- match a potential value...
-
- (DEFUN Call-Predicate (patternDirective potentialValue)
- "Call the predicate of the pattern directive to see if the value is
- okay."
- (COND
- ;; Is there a predicate to test?
- ((PatDir-Predicate? patternDirective)
- (EVAL `(,(PatDir-Predicate patternDirective)
- ',potentialValue
- ,@(PatDir-Params patternDirective))))
-
- ;; If no predicate to call, then return T
- (T)
- ))
-
- (DEFUN PatDir-Predicate (pattern-directive)
- (THIRD pattern-directive))
-
- (DEFUN PatDir-Params (pattern-directive)
- (CDDDR pattern-directive))
-
- In the interpreter it is probably not wise to spend the time compiling
- the predicate function (or LAMBDA) and then applying it to the
- potential value and other params. Is there any better solution than
- using this ugly backquoted EVAL?
-
- If I were going to match the pattern more than once I would use the
- pattern compiler. When the pattern interpreter is being used, the
- pattern is probably being matched one time only.
-
- BTW, I plan on posting these matchers to the cambridge.apple.com ftp
- site sometime in the future.
-
- Danny Brewer
- danny@farallon.com
-