XLISP mapcar

Nyquist / XLISP 2.0 - Contents | Tutorials | Examples | Reference

# mapcar

Type: | - | function (subr)
Source: | - | xllist.c

## Syntax

(mapcar function list1 [list2 ... ])
  function - a function definition like a lambda or a function name
  listN - a list or list expression
  returns - a list that is constructed from the results of the function applications

## Description

The mapcan function 'mapcar' applies the 'function' to the succesive cars of each of the lists 'listN'. Each of the lists supplies one of the arguments to 'function'. The 'mapcar' function returns a list that is constructed from the results of the 'function' applications. If the lists are of different lengths, the shortest list will determine the number of applications of 'function'.

## Examples

    > (mapcar #'+ '(1 2 3) '(1 2 3))
    (2 4 6)

    > (mapcar #'princ '(1 2 3))
    123       ; screen output
    (1 2 3)   ; return value

    > (mapcar #'+ '(1 2 3) '(1 2 3 4 5 6)  ; different length lists
    (2 4 6)

Note: The use of the 'function' will work properly when it is a sharp-quoted symbol, a quoted symbol [must be the name of a function], an unquoted symbol whose value is a function, or a closure object like a lambda form.

Bug: The proper syntax for 'function' when 'function' is a lambda expression is, for example:

    (mapcar #'(lambda (arg1 arg2) (+ arg1 arg2)) '(1 2))

and not:

    (mapcar '(lambda (arg1 arg2) (+ arg1 arg2)) '(1 2))

That is, the #' [function] read macro must be present. This error should be caught by the XLISP interpreter, but it is not, with the result that very obscure garbage collection bugs occur. [I still haven't tested Nyquist for possible garbage collection bugs caused by this.]

## Notes

In XLISP, a 'special form' of type FSUBR is not a function. This means that 'mapcar' only works with functions of type SUBR [built-in function] or CLOSURE [function defined by defun, flet, labels, or lambda], but with special forms of type FSUBR a 'bad function' error is signalled. Here is an example how to work around this behaviour:

    (defmacro mapcar* (function &rest args)
      (if (eq (type-of (symbol-function (second function))) 'fsubr)
          (let ((rest (gensym)))
            `(mapcar #'(lambda (&rest ,rest)
                         (eval (cons ,function ,rest)))
                     ,@args))
          `(mapcar ,function ,@args)))

Examples:

    (type-of #'eql)  => SUBR   ; built-in function
    (type-of #'and)  => FSUBR  ; built-in special form

    > (macroexpand-1 '(mapcar* #'eql '(1 2 3) '(t nil 3)))
    (MAPCAR (FUNCTION EQL)
            (QUOTE (1 2 3))
            (QUOTE (T NIL 3)))

    > (macroexpand-1 '(mapcar* #'and '(1 2 3) '(t nil 3)))
    (MAPCAR (FUNCTION (LAMBDA (&REST G7)
                        (EVAL (CONS (FUNCTION AND) G7))))
            (QUOTE (1 2 3))
            (QUOTE (T NIL 3)))

    (mapcar  #'eql '(1 2 3) '(t nil 3)))  => (NIL NIL T)
    (mapcar* #'eql '(1 2 3) '(t nil 3)))  => (NIL NIL T)

    (mapcar  #'and '(1 2 3) '(t nil 3)))  => error: bad function
    (mapcar* #'and '(1 2 3) '(t nil 3)))  => (T NIL 3)

Back to Top

Nyquist / XLISP 2.0 - Contents | Tutorials | Examples | Reference