7

Python's Itertools has what is called starmap. Given a collection of collections and a function, it applies the function to each collection strictly inside the collection, using the elements of said internal collection as arguments to the function. For example,

from itertools import starmap
 
NestedList = [(1, 2), (3, 4), (5, 6), (0, 0), (1, 1), (2, 2)]

list(starmap(lambda x, y:x + y, NestedList))

returns the list containing 3, 7, 11, 0, 2, and 4.

I refuse to believe that Python was the first to come up with this concept, but I'm drawing a blank when I try to think of what it was called in older languages. Does any analogous functionality exist in common lisp? I feel certain that it does, but I cannot name it.

J. Mini
  • 1,868
  • 1
  • 9
  • 38

3 Answers3

7

Use a combination of mapcar and apply:

(defun starmap (f list)
  (mapcar (lambda (x) (apply f x)) list))

Or loop with the keyword collect:

(defun starmap (f list)
  (loop for x in list 
        collect (apply f x)))

Examples:

> (starmap (lambda (x y) (+ x y)) '((1 2) (3 4) (5 6) (0 0) (1 1) (2 2)))
(3 7 11 0 2 4)

> (starmap #'expt '((1 2) (3 4) (5 6) (0 0) (1 1) (2 2)))
(1 81 15625 1 1 4)
Martin Půda
  • 7,353
  • 2
  • 6
  • 13
6

I refuse to believe that Python was the first to come up with this concept, but I'm drawing a blank when I try to think of what it was called in older languages. [...] I feel certain that it does, but I cannot name it.

To address this particular point, consider that Lispers or more generally functional programmers would say: "map the apply function". Consequently, a natural name would be mapply.

By looking for that name, you can see that there are indeed libraries like Serapeum that define it, but also that there are older references to this function (with the same meaning) from 1992 (H. Baker: Look'Lively Linear Lisp — 'Look Ma, No Garbage!') and probably before that too.

The fact that Python uses * to expand a list of values in the same way as apply explains why it is named starmap.

coredump
  • 37,664
  • 5
  • 43
  • 77
3

In common lisp that can be achieved using a combination of mapcar and apply.

(mapcar (lambda (lst) (apply (lambda (a b) (+ a b)) lst))
    '((1 2) (3 4)))

Similarly we can also implement it in javascript:

[[1, 2], [3, 4]].map(([x, y]) => x + y);

So starmap is nothing really new, just a convenient shortcut.

Matija Sirk
  • 596
  • 2
  • 15