http://www.perlmonks.org?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 }; }