From: ··········@yahoo.com.br
Subject: Help with lambda expression
Date: 
Message-ID: <7cc50ea9-63bf-45fd-8d1b-4f079d6c4140@a70g2000hsh.googlegroups.com>
(defun map (procedure list)
           (if (endp list) nil
               (cons (procedure (car list))
                     (map procedure (cdr list)))))
MAP

(defun scale-list (scale list)
           (map (lambda (item) (* item scale))
                list))
SCALE-LIST

(setq 1-to-4 (list 1 2 3 4))
(1 2 3 4)

(scale-list 10 1-to-4)

When I do this, the interpreter returns an error:
EVAL: undefined function PROCEDURE
   [Condition of type SYSTEM::SIMPLE-UNDEFINED-FUNCTION]

What am I doing wrong? Thanks.

From: Jochen Schmidt
Subject: Re: Help with lambda expression
Date: 
Message-ID: <5d3578d5-41bd-4f9b-aee1-ae0f101e2f17@a22g2000hsc.googlegroups.com>
On 11 Apr., 15:37, ··········@yahoo.com.br wrote:
> (defun map (procedure list)
>            (if (endp list) nil
>                (cons (procedure (car list))
>                      (map procedure (cdr list)))))
> MAP

The error faced is, that you use (procedure (car list)) instead of
(funcall procedure (car list)).
common lisp has different namespaces for variables and functions. A
symbol in the function position of a form is looked up in the function
namespace. Parameters of a function, like let-bindings use the
variable namespace. If you want to apply a function object you can
either use APPLY using a list of the actual arguments or use FUNCALL
as shown above.

Another possible bug: If you didn't shadow the symbol MAP in the
package you use, you would try to redefine the Common Lisp function
MAP in the above DEFUN; so you should either use a different name for
the function or define a new package which shadows the symbols of the
COMMON-LISP package you want to redefine:

(defpackage "MY-PACKAGE"
  (:use "COMMON-LISP")
  (:shadow "MAP"))

(in-package "MY-PACKAGE")

(defun map (procedure list)
  (if (endp list)
      nil
      (list* (funcall procedure (first list))
             (map procedure (rest list)))))

Since you're working (conceptually) with lists instead of conses: The
use of FIRST instead of CAR, REST instead of CDR and LIST* instead of
CONS makes this intent clear. This kind of definition may blow up your
stack-space quite quickly. This one would be better in most CL
implementations:

(defun map (procedure list)
  (labels ((rec (list acc)
             (if (endp list)
                  (nreverse acc)
                  (rec (rest list)
                       (list* (funcall procedure list)
                              acc)))))
    (rec list '())))

Or even better:

(defun map (procedure list)
  (loop for value in list
        collect (funcall procedure value)))

ciao,
Jochen

--
Jochen Schmidt
CRISPYLOGICS
Julienstr. 1, 90419 Nuremberg

Fon +49 (0)911 517 999 82
Fax +49 (0)911 517 999 83

mailto:(format nil "~(····@~36r.~36r~)"
               870180 1680085828711918828 16438)
http://www.crispylogics.com
From: Kent M Pitman
Subject: Re: Help with lambda expression
Date: 
Message-ID: <uve2oo3ia.fsf@nhplace.com>
··········@yahoo.com.br writes:

> (defun map (procedure list)
>            (if (endp list) nil
>                (cons (procedure (car list))
>                      (map procedure (cdr list)))))
> MAP

In Common Lisp, MAP is a pre-defined function, so know here that you
are redefining it (inappropriately).  That is not causing your
problem, but you should know it anyway.  Pick another name.

You want (funcall procedure (car list)) not just (procedure (car list)).
In Scheme you can call a variable's value by writing (variable ...).
In CL, variables and function names are in different "namespaces" and
you can't call a variable by just putting it in the car of a list.  You
must use funcall.

You will also eventually run into problems that Common Lisp does
require "tail call optimization" (as Scheme does) so writing your
procedure recursively will run out of stack space if you use long lists.
Eventually, in CL, you'll need to learn about iterative constructs to
avoid this.  But that is also not your problem right now.

Boa sorte!
 --Kent
From: Rupert Swarbrick
Subject: Re: Help with lambda expression
Date: 
Message-ID: <87d4owo5c7.fsf@gmail.com>
··········@yahoo.com.br writes:

> (defun map (procedure list)
>            (if (endp list) nil
>                (cons (procedure (car list))
>                      (map procedure (cdr list)))))
> MAP

The problems are all in here. Firstly, the reason your interpreter is
throwing a wobbly is that in the third line,

 (cons (procedure (car list)) ...)

actually means call the function which is in the function symbol table
and called procedure. Not what you want. Replace that by

 (cons (funcall procedure (car list)) ...)

and everything will work. *BUT*

You're defining a function called "map", which is exported by the
common-lisp package (which you'd better be importing else nothing'll
work). This is _bad_ since, apart from anything else, cl is locked so
you're not even supposed to be allowed to. SBCL makes you say "yes, I
know" at least once to let you do it.

Of course, you could actually use the normal version of map:

* (defun scale-list (scale list)
    (map 'list (lambda (item) (* item scale))
         list))

SCALE-LIST

* (scale-list 4 '(1 2 3 4))
(4 8 12 16)


But I appreciate that if this is a homework assignment you probably
can't.



Rupert