From: whampa
Subject: Syntax Question
Date: 
Message-ID: <bib6vg$10e$1@news-int.gatech.edu>
In the code below, the call (in caps) to helper gives me the error "Variable
HELPER has no value".  Am working on transitioning from scheme to lisp.
Could someone explain why it believes helper has no value?  Thank you!

(defun adj-list-to-edge-list (edgelst)
    (let (
            (helper (lambda (edges node)
                            (cond ((null edges) nil)
                                      (t (cons (list node (first edges))
                                                   (HELPER (rest edges)
node))))))
          )
        (cond ((null edgelst) nil)
                  (t (append (funcall helper
                                              (rest (first edgelst))
                                              (first (first edgelst)))
                                   (adj-list-to-edge-list (rest
edgelst)))))))

Examples of how code works:
(defparameter adjlist '((a b c) (b e) (c d) (d b c e)
		      (e d f h) (f e) (g h) (h e g)))

(adj-list-to-edge-list '((a b))) => ((A B))
(adj-list-to-edge-list '((a b c d))) => ((A B) (A C) (A D))
(adj-list-to-edge-list adjlist) => ((A B) (A C) (B E) (C D) (D B) (D C)
                                                 (D E) (E D) (E F) (E H) (F
E) (G H)
                                                 (H E) (H G))

From: Pascal Costanza
Subject: Re: Syntax Question
Date: 
Message-ID: <bib8mk$4jn$1@newsreader2.netcologne.de>
whampa wrote:

> In the code below, the call (in caps) to helper gives me the error "Variable
> HELPER has no value".  Am working on transitioning from scheme to lisp.
> Could someone explain why it believes helper has no value?  Thank you!

Common Lisp distinguishes between functions and other values. (It is 
called a Lisp-2 whereas Scheme is a Lisp-1.) You _either_ want this:

(defun ... (...)
   (flet ((helper (edges node) (cond (...))))
     ...
     (helper ...)
     ...))

_or_ this:

(defun ... (...)
   (let ((helper (lambda (...) ...)))
     ...
     (funcall helper ...)
     ...))


I hope this helps.

Pascal


> (defun adj-list-to-edge-list (edgelst)
>     (let (
>             (helper (lambda (edges node)
>                             (cond ((null edges) nil)
>                                       (t (cons (list node (first edges))
>                                                    (HELPER (rest edges)
> node))))))
>           )
>         (cond ((null edgelst) nil)
>                   (t (append (funcall helper
>                                               (rest (first edgelst))
>                                               (first (first edgelst)))
>                                    (adj-list-to-edge-list (rest
> edgelst)))))))
From: Edi Weitz
Subject: Re: Syntax Question
Date: 
Message-ID: <878ypi7o1q.fsf@bird.agharta.de>
On Sun, 24 Aug 2003 22:54:43 +0200, Pascal Costanza <········@web.de> wrote:

> whampa wrote:
> 
> > In the code below, the call (in caps) to helper gives me the error
> > "Variable HELPER has no value".  Am working on transitioning from
> > scheme to lisp.  Could someone explain why it believes helper has
> > no value?  Thank you!
> 
> Common Lisp distinguishes between functions and other values. (It is
> called a Lisp-2 whereas Scheme is a Lisp-1.) You _either_ want this:
> 
> (defun ... (...)
>    (flet ((helper (edges node) (cond (...))))
>      ...
>      (helper ...)
>      ...))

This won't work because HELPER calls itself recursively. And even it
did the FUNCALL at the end of the function's definition would
break. It'd had to be

  (funcall #'helper ...

instead.

> _or_ this:
> 
> (defun ... (...)
>    (let ((helper (lambda (...) ...)))
>      ...
>      (funcall helper ...)
>      ...))

This also won't work because of the recursive call.

Use LABELS:

(defun adj-list-to-edge-list (edgelst)
  (labels ((helper (edges node)
             (cond ((null edges) nil)
                   (t (cons (list node (first edges))
                            (helper (rest edges)
                                    node))))))
    (cond ((null edgelst) nil)
          (t (append (helper (rest (first edgelst))
                             (first (first edgelst)))
                     (adj-list-to-edge-list (rest edgelst)))))))

Edi.
From: Matthew Danish
Subject: Re: Syntax Question
Date: 
Message-ID: <20030824225219.GG1454@mapcar.org>
On Sun, Aug 24, 2003 at 11:17:53PM +0200, Edi Weitz wrote:
> On Sun, 24 Aug 2003 22:54:43 +0200, Pascal Costanza <········@web.de> wrote:
> > Common Lisp distinguishes between functions and other values. (It is
> > called a Lisp-2 whereas Scheme is a Lisp-1.) You _either_ want this:
> > (defun ... (...)
> >    (flet ((helper (edges node) (cond (...))))
> >      ...
> >      (helper ...)
> >      ...))
[snip]
> And even it did the FUNCALL at the end of the function's definition
> would break. It'd had to be
>   (funcall #'helper ...
> instead.

I don't understand this part.  What FUNCALL at the end of the function
definition?  

-- 
; Matthew Danish <·······@andrew.cmu.edu>
; OpenPGP public key: C24B6010 on keyring.debian.org
; Signed or encrypted mail welcome.
; "There is no dark side of the moon really; matter of fact, it's all dark."
From: Edi Weitz
Subject: Re: Syntax Question
Date: 
Message-ID: <87r83a5ggv.fsf@bird.agharta.de>
On Sun, 24 Aug 2003 18:52:19 -0400, Matthew Danish <·······@andrew.cmu.edu> wrote:

> I don't understand this part.  What FUNCALL at the end of the
> function definition?

The function definition was in the OP's question:
<············@news-int.gatech.edu>.

Edi.
From: Edi Weitz
Subject: Re: Syntax Question
Date: 
Message-ID: <874r067nq6.fsf@bird.agharta.de>
On Sun, 24 Aug 2003 16:27:33 -0400, "whampa" <·······@prism.gatech.edu> wrote:

> In the code below, the call (in caps) to helper gives me the error
> "Variable HELPER has no value".  Am working on transitioning from
> scheme to lisp.  Could someone explain why it believes helper has no
> value?  Thank you!
> 
> (defun adj-list-to-edge-list (edgelst)
>     (let (
>             (helper (lambda (edges node)
>                             (cond ((null edges) nil)
>                                       (t (cons (list node (first edges))
>                                                    (HELPER (rest edges)
> node))))))
>           )
>         (cond ((null edgelst) nil)
>                   (t (append (funcall helper
>                                               (rest (first edgelst))
>                                               (first (first edgelst)))
>                                    (adj-list-to-edge-list (rest
> edgelst)))))))
> 
> Examples of how code works:
> (defparameter adjlist '((a b c) (b e) (c d) (d b c e)
> 		      (e d f h) (f e) (g h) (h e g)))
> 
> (adj-list-to-edge-list '((a b))) => ((A B))
> (adj-list-to-edge-list '((a b c d))) => ((A B) (A C) (A D))
> (adj-list-to-edge-list adjlist) => ((A B) (A C) (B E) (C D) (D B) (D C)
>                                                  (D E) (E D) (E F) (E H) (F
> E) (G H)
>                                                  (H E) (H G))

It would be somewhat shorter do write it like this

  (defun foo (list)
    (loop for (first . rest) in list
          nconc (loop for x in rest
                      collect (list first x))))

if I understand you correctly.

Don't try to translate from Scheme to CL verbatim, try to learn the
language constructs CL has to offer.

Edi.
From: Matt Curtin
Subject: Re: Syntax Question
Date: 
Message-ID: <86fzjq4pjw.fsf@rowlf.interhack.net>
Edi Weitz <···@agharta.de> writes:

> Don't try to translate from Scheme to CL verbatim, try to learn the
> language constructs CL has to offer.

This is very good advice.  Many with a Scheme background will try to
make verbatim translation, thinking that "Scheme is a Lisp."  While it
can be argued that Scheme is a "Lisp-1", note that it's as heavily
influenced by Algol as it is by Lisp.

-- 
Matt Curtin, CISSP, IAM, INTP.  Keywords: Lisp, Unix, Internet, INFOSEC.
Founder, Interhack Corporation +1 614 545 HACK http://web.interhack.com/
Author of /Developing Trust: Online Privacy and Security/ (Apress, 2001)
From: Tristan (kesuari)
Subject: Re: Syntax Question
Date: 
Message-ID: <fNk2b.61600$bo1.35531@news-server.bigpond.net.au>
Matt Curtin wrote:
> This is very good advice.  Many with a Scheme background will try to
> make verbatim translation, thinking that "Scheme is a Lisp."  While it
> can be argued that Scheme is a "Lisp-1", note that it's as heavily
> influenced by Algol as it is by Lisp.

(Note: newbe alert.) Could you elaborate on this? Or point me to
somewhere that does?

Tristan.
From: Gareth McCaughan
Subject: Re: Syntax Question
Date: 
Message-ID: <87oeyeoflh.fsf@g.mccaughan.ntlworld.com>
"whampa" <·······@prism.gatech.edu> writes:

> In the code below, the call (in caps) to helper gives me the error "Variable
> HELPER has no value".  Am working on transitioning from scheme to lisp.
> Could someone explain why it believes helper has no value?  Thank you!

Is that the error you get if you start a new Lisp image,
enter that code, and try to use it? I'd be surprised if
so.

I get an error saying that "the function HELPER is undefined",
which is quite true. Common Lisp, unlike Scheme, allows a
symbol to have one value "as a variable" and a different
value "as a function"; the two are separate. So saying
(let ((helper ...)) ...) doesn't establish a *function*
binding for HELPER, so when you try to call HELPER as a
function it doesn't work.

So I'm guessing that you already have a definition for a
function called HELPER sitting around for some reason, and
that somewhere in there is a reference to a variable that
doesn't exist.

But ... If you amend the capitalized call to HELPER to
use FUNCALL, you *will* get a "variable is undefined"
error. That's because when the binding for HELPER
established by the LET is being set up, HELPER isn't
bound to anything. Therefore, the reference to HELPER
in that lambda expression is a reference to an unbound
variable. You really want something like Scheme's
LETREC here. CL doesn't have an equivalent of LETREC
for variable bindings, but for function bindings (which
are really what you want here) it has LABELS. Writing
your code in terms of LABELS, you get

    (defun adj-list-to-edge-list (edgelst)
      (labels ((helper (edges node)
                 (cond ((null edges) nil)
                       (t (cons (list node (first edges))
                                (helper (rest edges) node))))))
        (cond ((null edgelst) nil)
              (t (append (helper
                                  (rest (first edgelst))
                                  (first (first edgelst)))
                         (adj-list-to-edge-list (rest edgelst)))))))

which is probably what you want.

-- 
Gareth McCaughan
.sig under construc
From: Marco Antoniotti
Subject: Re: Syntax Question
Date: 
Message-ID: <3F49FE24.5050307@cs.nyu.edu>
whampa wrote:
> In the code below, the call (in caps) to helper gives me the error "Variable
> HELPER has no value".  Am working on transitioning from scheme to lisp.
> Could someone explain why it believes helper has no value?  Thank you!
> 
> (defun adj-list-to-edge-list (edgelst)
>     (let (
>             (helper (lambda (edges node)
>                             (cond ((null edges) nil)
>                                       (t (cons (list node (first edges))
>                                                    (HELPER (rest edges)
> node))))))
>           )
>         (cond ((null edgelst) nil)
>                   (t (append (funcall helper
>                                               (rest (first edgelst))
>                                               (first (first edgelst)))
>                                    (adj-list-to-edge-list (rest
> edgelst)))))))
> 

In Common Lisp, LET and LET* bind only values, not functions.  You need 
LABELS for what you want to do.  I.e. you need the equivalente of LETREC.

(defun adj-list-to-edge-list (edge-list)
     (labels ((helper (edges node)
                 (when edges
                    (cons (list node (first edges)
                          (helper (rest edges)))))
              )
        (when edge-list
          (append (helper (rest (first edge-list))
                          (first (first edgelist)))
                  (adj-list-to-edge-list (rest edge-list))))
     ))

Untested, bt it should work.

Cheers
--
Marco