Sohraab Strawbridge
Sohraab Strawbridge

Reputation: 13

can I use 'let' inside a 'cond' in a Scheme function?

newbie to Scheme, trying to write a function that takes a list, and three items as input, replaces item1 with item2, uses let to name it temporarily, then reverses this temp list and adds item3 to its end.

This is just for tinkering with Scheme and not a homework problem. Any advice is appreciated:

I have tried using let* without success, and removed cond and still in vain.

(define (itemreplacer item1 item2 item3 leest)
 (cond ( 
        (eq? (car leest) item1)
        (cons item2 (cdr leest)))
        (else
        (let
          (
           (templist (cons item1 (itemreplacer (cdr (leest))))))
          (reverse (cons item3 templist))))))

It works upto the point where the item2 replaces item1, and only shows this as output. Somehow, the reverse line does not run.

Upvotes: 1

Views: 169

Answers (1)

Óscar López
Óscar López

Reputation: 236004

The let expression is fine, that's not the problem. There are more serious issues with the code:

  • You forgot to write a base case for the recursion
  • It's preferred to use equal? for comparisons (it's more general)
  • Do not surround a value with brackets, unless it's a procedure you want to invoke, code like this will fail: (leest)
  • You're not providing the correct amount of parameters when recursively calling itemreplacer
  • The general idea of your solution isn't right. What we should use here is a helper procedure (or alternatively, a named let), to accumulate the partial results up until the point where we find item1

Because of the last item, I had to rewrite the logic of the procedure to meet the requirements:

(define (itemreplacer leest item1 item2 item3)
  (replacer-helper leest item1 item2 item3 '()))

(define (replacer-helper leest item1 item2 item3 acc)
  (cond ((null? leest) (reverse acc))
        ((equal? (car leest) item1)
         (append (reverse (cdr leest)) (cons item2 acc) (list item3)))
        (else
         (replacer-helper (cdr leest) item1 item2 item3 (cons (car leest) acc)))))         

Now it works as expected:

(itemreplacer '(1 2 4 6 7 8 9 10) 6 5 3)
=> '(10 9 8 7 5 4 2 1 3)

The behavior for the case when item1 was not found is unspecified, so I'll just return the original input:

(itemreplacer '(1 2 4 6 7 8 9 10) 13 5 3)
=> '(1 2 4 6 7 8 9 10)

Upvotes: 1

Related Questions