views:

256

answers:

3

(I finally posted and accepted an answer to the effect of "no, there isn't, and the question isn't actually that general".)

Consider the Common Lisp function 'mapcar'. It takes a function and some lists as arguments, and calls the function with arguments pulled from the same position in each list.

Do standard libraries typically have a similar function that takes a single list, where each element of the list is a list of arguments for the function? What is a function like that typically called whether "standard" or not? (This isn't meant to be a Lisp question, but it's the only functional language+library I halfway know.)

I guess I'm asking if an operation like (in pseudo-Lisp):

(mapcar (curry #'apply function-to-map) list-of-arg-lists)

already has a name that is common across multiple languages or libraries (in the same way that 'map' and 'reduce' are names for common operations, not just specific library functions).

Thanks.

+3  A: 

I nominate map-apply or maybe mapply if you want to just use it yourself or in a small group.

(defun map-apply (fn arg-lists)
    (mapcar (lambda (arg-list) (apply fn arg-list))
            arg-lists))

(map-apply #'+ '((1 2) (3 4 5)))
  =>
(3 12)

EDIT Of course yours isn't just pseudo-Lisp if you have curry:

(defun curry (f &rest values)
    (lambda (&rest more-values)
        (apply f (append values more-values))))
Harold L
That's certainly a plausible name. I'm hoping someone who knows multiple languages/libraries can tell me if there is a particularly common one.
jtolle
It looks good to me. This function is either trivial or useless in a typed functional language, so the main languages you're looking at are Lisp dialects and Erlang. `map-apply` sounds like a good Scheme name to me, although I like `mapply` because it's clever.
Nathan Sanders
Like I said, I don't really know any other functional languages, so that's interesting about this really *not* being a general question after all. I think even "trivial" utilities can be useful in any language, but I can see how this kind of utility wouldn't make any sense unless 'apply' works with a list, and not a set of arguments that conform to a specific function signature.
jtolle
The trouble with doing a list-based apply in a typed functional language is that lists themselves are typed, so they can't be used to represent the arguments to a function unless that function only takes one type of argument.
Chuck
Lists of a union type and ntuples are in practice equivalent to lists of heterogenous lists (though slightly more complicated to use), and they exist in Haskell and OCaml. Really the difference between mapping over a list of atoms and mapping over a list of lists is a fairly small one - map or zip or whatever will work the same way whether given numbers, symbols, or arbitrary structured data like lists or ntuples.
Justin Smith
+1  A: 

There's not really a typical "functional programming" name for that specific operation. In fact, the way I phrased the question presupposes a language that works like Lisp, where functions are applied to lists of arguments. It also assumes that "mapping" in the first place means doing something like Lisp's 'mapcar'.

Not every language works that way. For example, Haskell functions take only one typed argument (see the other answers and comments, and http://www.haskell.org/tutorial/index.html). Mapping a function that takes a tuple type over a list of that type is conceptually similar to the operation I was asking about, and in that case the relevant function is...'map'.

As far as Lisp is concerned, that's just the way the 'mapcar' version of mapping a function over arguments works - it zips up the lists it takes as inputs and applies the function to map to the resulting argument lists. Some other function could just as easily take the zipped argument lists instead and still be called some variant of "map".

My thanks to everyone who contributed to what was, for me, pretty educational.

jtolle
It works pretty well in statically typed languages. You just replace a variandic function with a list of lists, which is even more flexible. See my post!
Dario
My edit a few days ago removed the statement that Dario was talking about here - I had said that the question isn't really meaningful for "typed functional languages"...
jtolle
It's kind of awkward accepting my own answer, but I'm satisfied that it's the proper one for the question I asked.
jtolle
A: 

Consider the Common Lisp function 'mapcar'. It takes a function and some lists as arguments, and calls the function with arguments pulled from the same position in each list.

Do standard libraries typically have a similar function that takes a single list, where each element of the list is a list of arguments for the function?

Well, Haskell defines a series of zipWithN-functions which have similar effects to mapcar for constant argument counts.

zipWith (\a b -> a + b) [1, 2, 3] [1, 2, 3]                   => [2, 4, 6]
zipWith3 (\a b c -> a + b + c) [1, 2, 3] [1, 2, 3] [4, 5, 6]  => [6, 9, 12]

Generalizing this concept for a list of lists will result in this (naively implemented) function zipWithMany

zipWithMany :: ([a] -> b) -> [[a]] -> [b]
zipWithMany f lists 
    | any null lists = []
    | otherwise      = (f $ map head lists) : zipWithMany f (map tail lists)

Example:

zipWithMany sum [[1, 2, 3], [1, 2, 3], [1, 2]] => [3, 6]
Dario
I'm Haskell-illiterate, but from your answer and a quick Google, it sounds like the 'zipWith' functions work like the Lisp 'mapcar'. That is, they take a function and some lists, and then return a list of the result of applying the function to arguments drawn from the same position in each list. Do I have that part right?
jtolle
@jtolle: Yes, you got it right.
Dario
O.K., so how does the Haskell 'map' work when you have a function that takes multiple arguments? Can you give it a function which takes multiple typed arguments and a list of some kind of "tuple" type where each "tuple" contains the right set of arguments? (I know "tuple" has an actual meaning that I'm probably butchering here.) Or does it only expect a function of a single argument and a list of arguments of the right type, with 'zipWith' provided when you want to map with multiple arguments?
jtolle
@jtolle: In Haskell, every function just has a single parameter and a single output value though you can compose this together using tuples and currying.`Map` takes a function and a list of values and applied this function to each value.
Dario
Dario, Thanks. I see how different Haskell is from Lisp in the details, and how that really does make my original question specific to Lisp and languages that work like Lisp. I'm going to update my own answer later today to try to articulate that better.
jtolle