Domanda

Can someone explain to me how the recursion works in the following function? Specifically, I am interested in what happens when the function reaches its base case. Also, why is a named let used in this code? (I am not familiar with named lets)

(define (unzip list-of-pairs)
  (if (null? list-of-pairs)
   (cons '() '())
   (let ((unzipped (unzip (cdr list-of-pairs))))
         (cons (cons (car (car list-of-pairs)) (car unzipped))
               (cons (cdr (car list-of-pairs)) (cdr unzipped))))))
È stato utile?

Soluzione

The procedure shown doesn't have anything special about it, you're just iterating over a list of this form:

'((1 . 2) (3 . 4) (5 . 6))

The only "weird" part is that the output is building two lists instead of the usual single list. As you know, when we're building a single list as output the base case is this:

(if (null? lst) '() ...)

But here, given that we're simultaneously building two lists, the base case looks like this:

(if (null? lst) (cons '() '()) ...)

The code in the question is not using a named let, it's just a plain old garden-variety let, there's nothing special about it. It's useful because we want to call the recursion only once, given that we need to obtain two values from the recursive call.

If we don't mind being inefficient, the procedure can be written without using let, at the cost of calling the recursion two times at each step:

(define (unzip list-of-pairs)
  (if (null? list-of-pairs)
      (cons '() '())
      (cons (cons (car (car list-of-pairs))
                  (car (unzip (cdr list-of-pairs))))
            (cons (cdr (car list-of-pairs))
                  (cdr (unzip (cdr list-of-pairs)))))))

Of course, the advantage of using let is that it avoids the double recursive call.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top