Why don't people like lisp?

prunesquallor at comcast.net prunesquallor at comcast.net
Thu Oct 23 19:14:56 EDT 2003


Marcin 'Qrczak' Kowalczyk <qrczak at knm.org.pl> writes:

> On Thu, 23 Oct 2003 12:11:30 -0400, Joe Marshall wrote:
>
>> So if we extended Lisp, for example, I could write:
>
>> (defun pythagorean-triples (n)
>>   (all-values
>>     (let ((opposite (an-integer-between 1 n))
>>           (adjacent (an-integer-between 1 n))
>>           (hypotenuse (an-integer-between 1 n)))
>>       (if (= (+ (* opposite opposite)
>>                 (* adjacent adjacent))
>>              (* hypotenuse hypotenuse))
>>           (list opposite adjacent hypotenuse)
>>           (fail)))))
>
> How to write such macros in Lisp? Looks like they would require non-local
> rewriting of program structure, I don't see how it's possible at all.

It ain't easy, but it is possible.  (In Scheme it is a bit easier
because of first-class continuations, but that's a different issue.)

The key point here is that the authors (Jeffrey Mark Siskind and David
McAllester) of the macros didn't have to implement an entire
non-deterministic language, they merely had to extend the existing one
with a small well-designed set of macros.  Things like garbage
collection, interrupts, unwind-protect, parsers, code-generators,
file-system i/o, etc. are time consuming and tricky.  By extending
an existing known implementation, they finesse *all* that work.

Additionally, I don't have to learn an entire domain-specific language
to use their package.  I learn a few extra macros and I'm done.



(pprint (macroexpand '(all-values
                        (let ((a (an-integer-between 1 n))
                              (b (an-integer-between 1 n))
                              (c (an-integer-between 1 n)))
                         (unless (= (+ (* a a) (* b b)) (* c c)) (fail))
                         (list a b c)))))

=>

(LET* ((VALUES 'NIL) (LAST-VALUE-CONS NIL) (TRAIL-POINTER (FILL-POINTER *TRAIL*)))
  (CATCH 'FAIL
    (LET ((*NONDETERMINISTIC?* T))
      (UNWIND-PROTECT
          (PROGN
            (LET* ((#:DUMMY-728 N)
                   (#:CONTINUATION-730
                    (LAMBDA (&OPTIONAL #:DUMMY-710 &REST #:OTHER-711)
                      (LET* ((#:DUMMY-723 N)
                             (#:CONTINUATION-725
                              (LAMBDA (&OPTIONAL #:DUMMY-712 &REST #:OTHER-713)
                                (LET* ((#:DUMMY-718 N)
                                       (#:CONTINUATION-720
                                        (LAMBDA (&OPTIONAL #:DUMMY-714 &REST #:OTHER-715)
                                          (LET ((C #:DUMMY-714)
                                                (B #:DUMMY-712)
                                                (A #:DUMMY-710))
                                            (IF (NULL (= (+ (* A A) (* B B)) (* C C)))
                                                (FAIL))
                                            (LET* ((#:DUMMY-708 (LIST A B C))
                                                   (VALUE #:DUMMY-708))
                                              (GLOBAL
                                                (COND ((NULL VALUES)
                                                       (SETF LAST-VALUE-CONS (LIST VALUE))
                                                       (SETF VALUES LAST-VALUE-CONS))
                                                      (T
                                                       (SETF
                                                        (REST LAST-VALUE-CONS)
                                                        (LIST VALUE))
                                                       (SETF
                                                        LAST-VALUE-CONS
                                                        (REST LAST-VALUE-CONS)))))
                                              (FAIL))))))
                                  (AN-INTEGER-BETWEEN-NONDETERMINISTIC
                                   #:CONTINUATION-720
                                   1
                                   #:DUMMY-718)))))
                        (AN-INTEGER-BETWEEN-NONDETERMINISTIC
                         #:CONTINUATION-725
                         1
                         #:DUMMY-723)))))
              (AN-INTEGER-BETWEEN-NONDETERMINISTIC #:CONTINUATION-730 1 #:DUMMY-728)))
        (BLOCK NIL
          (TAGBODY
           LOOP    (IF (= (FILL-POINTER *TRAIL*) TRAIL-POINTER) (RETURN))
                   (FUNCALL (VECTOR-POP *TRAIL*))
                   (SETF (AREF *TRAIL* (FILL-POINTER *TRAIL*)) NIL)
                   (GO LOOP))))))
  VALUES)




More information about the Python-list mailing list