''map'' is one of the CommonHigherOrderFunctions which transforms a list by applying a function to each of its elements. Its return value is the transformed list. For example: (map double (list 1 2 3 4 5)) => (2 4 6 8 10) (map send-email (list message1 message2 message3)) => (ok bad-recipient-list ok) There are many variations on the map function, the one described here is called ''map'' in Scheme, and ''mapcar'' in most Lisps. ------ ''map'' is doubly (ha) useful when used with anonymous functions In CommonLisp: (mapcar (lambda (x) (* 2 x)) (list 1 2 3 4 5)) => (2 4 6 8 10) In PerlLanguage: DB<1> x map { 2 * $_ } (1,2,3,4,5) 0 2 1 4 2 6 3 8 4 10 (this is using the perl debugger as a poor man's top-level loop. The comand "x" means "evaluate and display the return value") In SmalltalkLanguage: #collect: #(1 2 3 4 5) collect: [:each | 2 * each] In PythonLanguage: map(lambda x: 2*x, (1, 2, 3, 4, 5) ) Version 2.0 of PythonLanguage has ListComprehension''''''s, which are nice syntactic sugar for map: [2*x for x in (1, 2, 3, 4, 5)] In RubyLanguage [1, 2, 3, 4, 5].map { |x| 2*x } In CsharpLanguage 2.0 or greater int[] a = { 1, 2, 3, 4, 5 }; int[] b = Array.Convert''''''All(a, delegate(int n) { return n*2; }); In CsharpLanguage 3.0 or greater int[] a = { 1, 2, 3, 4, 5 }; var b = a.Select(n => n * 2); // uses built-in Select operator over sequences var c = from n in a select n * 2; // list comprehension syntax over previous example In CeePlusPlus (C++) using the StandardTemplateLibrary int a[5] = {1, 2, 3, 4, 5}; transform( a, a+5, a, bind1st( times(), 2 ) ); (or a.begin() and a.end() if you instead used a vector for 'a') Note: You can use another collection or the same collection to store the result. In HaskellLanguage map (2*) [1,2,3,4,5] In OcamlLanguage List.map ((*) 2) [1;2;3;4;5] Array.map ((*) 2) [|1;2;3;4;5|] In SmlLanguage map (fn x => x * 2) [1,2,3,4,5] Vector.map (fn x => x * 2) #[1,2,3,4,5] In JavaScript 1.6, arrays have a method called "map": var evens = numbers.map(function(x){return x * 2;}); In SchemeLanguage: (map (lambda (x) (* x 2)) numbers) Note that Scheme's map is more general than described here. It actually accepts an n-ary function followed by n lists, each of length M. The output is a single list of length M, composed by calling the given function with arguments taken from the 'm'th element of each list. e.g.: (map add (list 1 2 3) (list 4 5 6)) -> (5 7 9) In PhpLanguage: array_map(create_function('$x', 'return 2 * $x;'), array(1, 2, 3, 4, 5)) In SwiftLanguage: [1,2,3,4,5].map { 2 * $0 } In StructuredQueryLanguage (SQL): select x * 2 as Double // make sure not a reserved word from original_list Note you must use an expression, since many dialects don't allow user-defined functions (or don't make it easy). ---- One of the nice things about the RubyLanguage is that these iterated constructs can be programmed in the language. A method may be passed a closure, and within the method you can coroutine with that closure using the 'yield' construct. def silly yield "one" yield "two" yield "three" end silly { |s| puts s } # outputs one, two, three So, for example, Ruby doesn't have the equivalent of Smalltalk's 'inject'. However, it's simple to write one. If we assume the existence of an InternalIterator in the current class called 'each', which invokes its closure for each element in a collection (a Ruby convention), then 'inject' would be class ACollection # ... def inject(n) each { |value| n = yield(n, value) } n end end a = ACollection.new sum = a.inject(0) { |result, value| result + value } product = a.inject(1) { |result, value| result * value | and so on. In fact, you'd probably define ''inject'' as a method in the existing module ''Enumerable,'' and every collection would automatically support it from then on. It's fun to be able to code so flexibly in this functional style. ''Actually ruby has #inject since version 1.8'' ---- ''Hmmmm... I"ve always thought of ''map'' as being more like ''#do'' in SmallTalk. It ''allows'' you to create a new list, but it doesn't ''necessarily'' create a new collection object. For example, the ''map'' function in Perl acts much like #do in SmallTalk. You can print each item in the list, apply a procedure, create a new collection just of evaluation results, or not. I think the problem is the way input and output work in a Functional Language as opposed to an ObjectOriented language like SmallTalk. In something like map, you can compose by giving it another iterator as an argument, instead of just some expression to evaluate on each member. This makes it '''seems''' like it works as #collect but it actually operates like #do, just in a functional environment. I'm just kind of guessing, is this assumption incorrect?'' I'm afraid it is incorrect. ''map'' as in Scheme always creates a new list. The equivalent of 'do:' is for-each (a standard scheme procedure). See http://www-swiss.ai.mit.edu/~jaffer/r5rs_8.html#SEC48 (define (for-each f lst) (if (not (null? lst)) (begin (f (car lst)) (for-each f (cdr lst))))) In CommonLisp, mapcar is the MapFunction as described here, and mapc behaves like Scheme's for-each. There are a few related functions: maplist, mapl, mapcan, and mapcon. The last two are very seldom needed... ---- If we construe lists (and kindred collection types) as mappings (input is the index, hash key or whatever; bags and similar need to be construed, via iteration, as lists to fit them into this concept) then we can regard map as simply the composition operation among functions. A list h, in these terms, is just a function h[i] <- i from some initial subset, n, of the naturals (so i is in n). Our function f is then f(x) <- x and map(f, h) is just f(h[i]) <- i which is simply the result of composing f after h; it's f function from n, just as h was (so it's a list) which feeds h's input through h and h's output through f. ----- One of the distinguishing characteristics of ExBase is a kind of MapFunction capability over a given table, but also with predicate filtering, similar to an SQL "WHERE" clause. (Early dialects only allowed this on built-in functions, not user-defined ones.) Pseudo-code for it would resemble: Perform function a() on table b where x > y and foo=7 Ideally, a reference to the current "row" would be passed to the function, but ExBase used a more primitive default scope for such. This simplified rapid prototyping and interactive work, but would not work well for large shared libraries. ---- CategoryFunctionalProgramming CategoryInManyProgrammingLanguages CategoryObjectFunctionalPatterns