From: Gerald Smith
Subject: "On Lisp" book
Date: 
Message-ID: <5imes7$ppc$1@mhadf.production.compuserve.com>
Guilty of cross-posting in two forums, but I am desperate.

I know very little Scheme, but am trying to demonstrate to some of 
my colleagues a few of the features that Scheme has, 
compared to Common Lisp. (CL is my language of choice)

I am using a CL book titled    On Lisp   by Paul Graham - - even though 
it is a CL book, the author uses Scheme code to make some points.

Unfortunately, (for me) the author assumes the reader has a fair level 
of Scheme competence.



Here is the Scheme function I am trying to get working, page 303 of 'On Lisp'


(define (path node1 node2)
  (cond ((null? (neighbors node1)) (fail))
        ((memq node2 (neighbors node1)) (list node2))
        (else (let ((n (choose (neighbors node1) )))
                (cons n (path n node2))) )))


The problem is, the author left out the definition of the NEIGHBORS function, 
so I can't get the PATH function to work.

Here is the diagram, the aim of the PATH function is to return the 
shortest path from node A to node E


                  C
                 / \
                /   \
               /     \
              /       \
             A---------B
              \
               \
                \
                 \
                  D------E



I derived the input node arguments for PATH with the following code. 
This code may be in error, the author did not specify how to make 
the arguments for PATH.

(define node-a)
(define node-e)

(set! node-a '(a b (c) (d . e)))

(set! node-e (cdr (cadddr node-a)))

(begin (set-cdr! (caddr node-a) node-a) 'done)


Be careful, node-a now contains of a circular list, if you try to evaluate it by itself you will get trapped in an endless loop.

   node-a  ===> (a b (c a b (c a b (c a b etc. etc.


Using these arguments, 'path' will be ran this way:

(path node-a node-e)

hopefully returning either  (a d e)   or   (a d . e)



The definition of CHOOSE and FAIL are below, from page 304 of 'On Lisp'

******************************************************
(define *paths* '() )

(define failsym ยท@)  ;; non-special usage, therefore no asterisks

(define call/cc  call-with-current-continuation)  ;; alias for convenience


(define (choose choices)
  (call/cc
    (lambda (cc)
       (set! *paths* (append *paths*
                             (map (lambda (choice)
                                     (lambda () (cc choice)))
                                  choices)))
       (fail) )))



;; the variable 'fail' starts life as a non-special global variable,
;; will be 'captured' and actually used as a function.

(define fail)



;; the code below  _is_  the continuation.  Scheme will automatically
;; use it wherever cc appears in the CHOOSE function.  (i think)

(call/cc
  (lambda (cc)
    (set! fail
          (lambda ()
             (if (null? *paths*)
                 (cc failsym)
                 (let ((p1 (car *paths*)))
                   (set! *paths* (cdr *paths*))
                   (p1) ))) )))

***************************************************
End of definitions of CHOOSE and FAIL



If any one has worked their way though this particular PATH function 
in Paul Graham's Common Lisp book "On Lisp" and actually got it 
to work, I would be very interested in knowing how.

Gerald