http://qs321.pair.com?node_id=128738


in reply to mapcar -- map for more than one list

I'm not sure this is right.

The e-LISP mapcar, according to the info page "(elisp) Mapping Functions", is defined as follows:

 - Function: mapcar FUNCTION SEQUENCE
     `mapcar' applies FUNCTION to each element of SEQUENCE in turn, and
     returns a list of the results.

     The argument SEQUENCE can be any kind of sequence except a
     char-table; that is, a list, a vector, a bool-vector, or a string.
     The result is always a list.  The length of the result is the
     same as the length of SEQUENCE.

IANALH, but that sounds remarkably like Perl's map function.

However, it does go on to provide an example which seems to do (almost) the same thing that your mapcar does:

(defun mapcar* (function &rest args) "Apply FUNCTION to successive cars of all ARGS. Return the list of results." ;; If no list is exhausted, (if (not (memq 'nil args)) ;; apply function to CARs. (cons (apply function (mapcar 'car args)) (apply 'mapcar* function ;; Recurse for rest of elements. (mapcar 'cdr args))))) (mapcar* 'cons '(a b c) '(1 2 3 4)) => ((a . 1) (b . 2) (c . 3))

Besides that, "car" is an old term coming from the term "Contents of the Address part of the Register". I don't know where you got mapcaru from.

Perhaps this is a common lisp vs e-lisp thing, as I found at least one page that makes reference to mapcar behaving in the way you specify.

I suggest the name mapshift instead of mapcar, for the version that returns short lists. The other one should perhaps be called something else, like mapfor or mapforeach perhaps.

Here is a new one, too - mapeach, which works on hash refs passed to it:

sub mapeach (&\%) { my $sub = shift; my $hash = shift or do { require Carp; Carp::croak( "mapeach: Nothing to map" ); }; my @ret; while ( my ($k, $v) = each %{$hash}) { local ($_) = $k; push @ret, $sub->($k, $v); } return wantarray ? @ret : { @ret }; }

Replies are listed 'Best First'.
Re: Re: mapcar -- map for more than one list
by runrig (Abbot) on Dec 01, 2001 at 01:48 UTC
    Some lisp's have a limited mapcar which can only operate on one list (making it like perl's map), but in other lisp's mapcar will operate on a list of lists, taking the car of each list, making a list from that, and using that as the first argument to the function, then taking the next element of each list, etc., and returning a list of the results. I think Common Lisp has the limited version, I'm not positive. The Lisp's I've used, AutoLISP and UCI LISP (long ago), both would take a list of lists.

    And tye's 'mapcaru' ('mapcar', but use the (u)ndefined value for missing elements) was just a different implementation which deals with lists of differing lengths in a different way.

      Common Lisp's mapcar can accept lists of lists. However it only iterates as long as all lists have more elements. In other words its handling of unequal lists is to stop rather than trying to continue calling while indicating the missing elements in some way.