Common Lisp equivalent of Python's itertools.starmap?
Asked Answered
L

3

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.

Lavin answered 12/1, 2023 at 9:5 Comment(0)
G
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)
Gramps answered 12/1, 2023 at 9:28 Comment(0)
R
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.

Rhiana answered 12/1, 2023 at 9:36 Comment(4)
Direct link: github.com/ruricolist/serapeum/blob/master/…Jesus
@Jesus Thanks, that's a better link indeedRhiana
R's mapply is basically just map. In fact, R's Map is just a wrapper for mapply.Lavin
@J.Mini Thanks, I think it's better if I just remove this part from the answerRhiana
A
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.

Agueda answered 12/1, 2023 at 9:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.