Search code examples
functional-programminglispracketsicp

Building map with Racket


I was building the map function as a matter of practice.

I came up with the following code:

#lang racket

(define (map procedure items)
  (if (null? items)
      empty
      (cons (procedure (car items)) (map procedure (cdr items)))))

I tried this and it worked fine:

(map add1 '(1 2 3))

>> '(2 3 4)

Then I tried this and it also worked fine:

(define (scale-by-3 item)
  (* 3 item))

(map scale-by-3 '(1 2 3))

>> '(3 6 9)

After that, I decided to generalize the scale procedure:

(define (scale-by-factor factor item)
  (* factor item))

This scale-by-factor function works:

(scale-by-factor 3 4)

>> 12

But when I tried using it with the map:

(map (scale-by-factor 2 item) '(1 2 3))

I got the following error:

item: unbound identifier in module in: item

How do I solve this? Is there a way of solving it without lambda?


Solution

  • It fails because item doesn't exist at the time you call it - it's passed by map as a parameter when traversing the list. To solve the problem, do something like this:

    (map (lambda (item) (scale-by-factor 2 item))
         '(1 2 3))
    

    Or we can write a nicer alternative using curry, which creates a lambda that expects the missing item parameter:

    (map (curry scale-by-factor 2)
         '(1 2 3))