5

In Scheme, the function (map fn list0 [list1 .. listN]) comes with the restriction that the lists must have the same number of elements. Coming from Python, I'm missing the freedom of Python list comprehensions, which look a lot like map above, but without this restriction.

I'm tempted to implement an alternative "my-map", which allows for lists of differing size, iterating through the first N elements of all lists, where N is the length of the shortest list.

For example, let num be 10 and lst be (1 2 3). With my-map, I hope to write expressions like:

(my-map + (circular-list num) lst)))

And get:

(11 12 13)

I have an easier time reading this than the more conventional

(map + (lambda (arg) (+ num arg)) lst)

or

(map + (make-list (length lst) num) lst) 

Two questions:

  • As a Scheme newbie, am I overlooked important reasons for the restriction on `map`?
  • Does something like `my-map` already exist in Scheme or in the SRFIs? I did take a look at srfi-42, but either it's not what I'm looking for, or it was, and it wasn't obvious.
Will Ness
  • 70,110
  • 9
  • 98
  • 181
SuperElectric
  • 17,548
  • 10
  • 52
  • 69
  • what does list comprehensions have to with map on multiple lists? – newacct May 23 '11 at 08:57
  • @newacct I wanted map on a single empty list to behave like a Python list comprehension on an empty list. In other words, I wanted it to return an empty list, rather than to throw an error. For multiple lists, I wanted map to stop once the shortest list was depleted, like with Python's [f(x, y) for x, y in zip(x_list, y_list)]. As Eli points out, the srfi-1 version of map does both of these things, while the built-in (r5rs) version of map doesn't. – SuperElectric May 23 '11 at 18:04
  • R5RS (http://schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-9.html#%_idx_558) doesn't say that the lists can't be empty (as Eli Barzilay points out in the beginning of his answer) – newacct May 24 '11 at 20:16
  • Whoops; true. I can't even remember where I got that idea from. – SuperElectric May 25 '11 at 19:34
  • I've edited the question to remove the false assertion that r5rs' map disallows empty lists. – SuperElectric Jun 04 '11 at 23:08

1 Answers1

7

First, note that map does allow empty lists, but of course if there's one empty list then all of them should be empty.

Second, have a look at the srfi-1 version of map -- it is specifically different from the R5RS version as follows:

This procedure is extended from its R5RS specification to allow the arguments to be of unequal length; it terminates when the shortest list runs out.

Third, most Scheme programmers would very much prefer

(map (lambda (arg) (+ num arg)) lst)

My guess is that Scheme is different from Python in a way that makes lambda expressions become more and more readable as you get used to the language.

And finally, there are some implementations that come with some form of a list comprehension. For example, in Racket you can write:

(for/list ([arg lst]) (+ num arg))
Eli Barzilay
  • 29,301
  • 3
  • 67
  • 110