From: danny@farallon.com (Danny Brewer)
Newsgroups: comp.lang.lisp
Subject: Re: Can I use EVAL?
Date: 28 Aug 92 16:05:17 GMT
Followup-To: comp.lang.lisp
Organization: Farallon Computing, Inc.

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
Newsgroups: comp.lang.lisp