From: bd
Subject: Newbie needs help
Date: 
Message-ID: <h9o7ha.ht6.ln@ID-151211.user.dfn.cis.de>
I've just started learning lisp, and I'm trying to write a 'foreach' 
function, ala perl.  Can someone tell me why the following code gets me *** 
- EVAL/APPLY: too few arguments given to :LAMBDA?

(defun get-list-entry (l n)
  (if (= n 0)
      (first l)
    (get-list-entry l (- l 1))
    )
  )

(defun unilist (x)
  (if (= (type-of x) (type-of '(x))) x (cons x nil)))

(defun foreach (l cmd)
  (if (= (list-length l) 0) nil
    (append
     (unilist (apply cmd (first l)))
     (foreach (rest l) cmd)
     )
    )
  )

(foreach '("x" "y" "z") (lambda (x) (write-line x)))

-- 
bd has lost all his data - donate your bits to the bd_'s harddrive
restoration drive! One free campaign pin per bit bucket!

From: Geoffrey Summerhayes
Subject: Re: Newbie needs help
Date: 
Message-ID: <vlKZ8.9096$QY4.1475188@news20.bellglobal.com>
"bd" <·······@users.sf.net> wrote in message
··················@ID-151211.user.dfn.cis.de...
> I've just started learning lisp, and I'm trying to write a 'foreach'
> function, ala perl.  Can someone tell me why the following code gets me
***
> - EVAL/APPLY: too few arguments given to :LAMBDA?

Already done, read up on map and its relatives.

(mapcar (lambda (x) (write-line x)) '("X" "Y" "Z"))

> (defun get-list-entry (l n)
>   (if (= n 0)
>       (first l)
>     (get-list-entry l (- l 1))
>     )
>   )

(defun get-list-entry (list n)
    (if (zerop n)
        (first list)
      (get-list-entry (rest list) (- n 1))))

or

(nth n list)

> (defun unilist (x)
>   (if (= (type-of x) (type-of '(x))) x (cons x nil)))
>

(defun unilist (x)
  (if (consp x) x (cons x nil)))
or
  (if (listp x) x (list x)))

> (defun foreach (l cmd)
>   (if (= (list-length l) 0) nil
>     (append
>      (unilist (apply cmd (first l)))

Not the usual idea, if (cmd (first l)) returns 1, (1 1), and 1 you'll get (1
1 1 1)  instead of (1 (1 1) 1)
Does foreach in perl actually do this?

>      (foreach (rest l) cmd)
>      )
>     )
>   )
>
-----------------------
: (funcall #'+ 1 2)
3

: (apply #'+ 1 2)

Error

: (apply #'+ '(1 2))
3
-----------------------

(defun foreach (list fn)
  (if (null list) nil
    (append
     (unilist (funcall fn (first list)))
     (foreach (rest list) fn))))

--
Geoff
From: bd
Subject: Re: Newbie needs help
Date: 
Message-ID: <nds7ha.767.ln@ID-151211.user.dfn.cis.de>
Geoffrey Summerhayes wrote:

> 
> "bd" <·······@users.sf.net> wrote in message
> ··················@ID-151211.user.dfn.cis.de...
>> I've just started learning lisp, and I'm trying to write a 'foreach'
>> function, ala perl.  Can someone tell me why the following code gets me
> ***
>> - EVAL/APPLY: too few arguments given to :LAMBDA?
> 
> Already done, read up on map and its relatives.
> 
> (mapcar (lambda (x) (write-line x)) '("X" "Y" "Z"))

I don't understand...

> Not the usual idea, if (cmd (first l)) returns 1, (1 1), and 1 you'll get
> (1
> 1 1 1)  instead of (1 (1 1) 1)
> Does foreach in perl actually do this?

No, foreach evaluates a given block of code for each element in a list, 
putting the elements in a scalar variable each time through.

-- 
bd has lost all his data - donate your bits to the bd_'s harddrive
restoration drive! One free campaign pin per bit bucket!
From: Friedrich Dominicus
Subject: Re: Newbie needs help
Date: 
Message-ID: <87y9c8gvdk.fsf@fbigm.here>
bd <·······@users.sf.net> writes:

> 
> No, foreach evaluates a given block of code for each element in a list, 
> putting the elements in a scalar variable each time through.
Have not read all but as pointed out before the map functions do that
quite well or if you have a list dolist is you're friend

(defun for-each (fun list)
        (dolist (item list)
           (funcall fun item)))

or using the loop facility
(defun for-each-with-loop (fun list)
        (loop for item in list
             do (funcall fun item)))

Regards
Friedrich
From: Kaz Kylheku
Subject: Re: Newbie needs help
Date: 
Message-ID: <ah84bq$qkc$2@luna.vcn.bc.ca>
In article <·············@ID-151211.user.dfn.cis.de>, bd wrote:
>Can someone tell me why the following code gets me *** 
> - EVAL/APPLY: too few arguments given to :LAMBDA?
> 
> (defun get-list-entry (l n)
>   (if (= n 0)
>       (first l)
>     (get-list-entry l (- l 1))
>     )
>   )

Lisp has a function called NTH which does this. 
(nth 1 '(1 2 3)) yields 2.

> (defun unilist (x)
>   (if (= (type-of x) (type-of '(x))) x (cons x nil)))

This is cryptic because the x in '(x) is not evaluated; it is just
a dummy symbol. And note that Lisp has no ``list of 1 element'' type.
The type of '(x) is cons. Also, don't compare types with the =
operator, they are not numbers. So your function means this:

  (if (consp x) 
    x
    (cons x nil))

In other words, if x is a cons, then return it, otherwise return a cons whose
CAR is x. The consp function is a standard predicate for asking whether an
object is a cons. To test whether an object is one of several types, and take
action, use the typecase or etypecase macros.

> (defun foreach (l cmd)
>   (if (= (list-length l) 0) nil
>     (append
>      (unilist (apply cmd (first l)))

You want funcall here, since you just want to call a function and give
it a single parameter.  The apply function is used when you want to turn the
items of a list into individual parameters.  The last parameter of apply must
be a list, so for example

  (apply #'mangle 1 2 3 4 (list 5 6))

is equivalent to (mangle 1 2 3 4 5 6). The first four arguments
are passed down straight, and the last one is a list which is
``unpacked'' to produce the remaining arguments.

> (foreach '("x" "y" "z") (lambda (x) (write-line x)))

Of course, Lisp doesn't need your heroic effort, because
the for-each constructs are already there:

(mapc #'write-line '("x" "y" "z"))

(dolist (line '("x" "y" "z"))
  (write-line line))
From: Marco Antoniotti
Subject: Re: Newbie needs help
Date: 
Message-ID: <y6c8z473d8w.fsf@octagon.mrl.nyu.edu>
bd <·······@users.sf.net> writes:

> I've just started learning lisp, and I'm trying to write a 'foreach' 
> function, ala perl.

First of all it is Perl that has a `foreach' statement similar to the
godzillion ones that have appeared in Lisp over the years :)


  Can someone tell me why the following code gets me *** 
> - EVAL/APPLY: too few arguments given to :LAMBDA?
> 
> (defun get-list-entry (l n)
>   (if (= n 0)
>       (first l)
>     (get-list-entry l (- l 1))
>     )
>   )

This function you wrote is built in.  It is called `elt'.

> (defun unilist (x)
>   (if (= (type-of x) (type-of '(x))) x (cons x nil)))

What is that you are trying to do here?  Already it looks like you
have a mistake.

        (type-of '(x))

will always return

        cons

The rest is funky.

> 
> (defun foreach (l cmd)
>   (if (= (list-length l) 0) nil
>     (append
>      (unilist (apply cmd (first l)))
>      (foreach (rest l) cmd)
>      )
>     )
>   )

(dolist (x l) (cmd x)) ?


> 
> (foreach '("x" "y" "z") (lambda (x) (write-line x)))

This is called `map'.

        (map nil (lambda (x) (print x)) '("x" "y" "z"))

Or you can do it using the standard DOLIST and LOOP constructs

        (dolist (x l)
           (funcall (lambda (x) (print x)) x)) ; Note the proper scoping of 'x'!

        (loop for x in l
           do (funcall (lambda (z) (print z)) z))

Cheers

-- 
Marco Antoniotti ========================================================
NYU Courant Bioinformatics Group        tel. +1 - 212 - 998 3488
719 Broadway 12th Floor                 fax  +1 - 212 - 995 4122
New York, NY 10003, USA                 http://bioinformatics.cat.nyu.edu
                    "Hello New York! We'll do what we can!"
                           Bill Murray in `Ghostbusters'.