user4706184
user4706184

Reputation:

Scheme - Function recursion error

This function reads in a list and swaps values, but only when there's a key in the hash table that matches an element in the list. However, the list that is read in could contain other lists, and I want to check this recursively. I use if (list? elementInList) to determine whether I'm dealing with a list, so I can search that list for elements that may need to be swapped using a recursive call. I tried to do this but it's not handling the lists within the list correctly. What am I doing wrong?

(define (let-helper L)
    (map (lambda (x) (swap x (hash-ref *variable-table* x) L))
         (filter (lambda (x) 
                     (if (list? x)
                         (let-helper x) ;; recursion here
                         (hash-has-key? *variable-table* x)))
                 L)))

Upvotes: 0

Views: 58

Answers (1)

Dan D.
Dan D.

Reputation: 74645

I'd suggest just flattening the list so that you can continue to use map and filter like this:

(define (let-helper L)
  (map (lambda (x) (swap x (hash-ref *variable-table* x) L))
       (filter (lambda (x) (hash-has-key? *variable-table* x))
               (flatten L))))

Otherwise to get it to work would require writing it without map and filter like this:

(define (let-helper L)
  (let ((action (lambda (x) (swap x (hash-ref *variable-table* x) L)))
        (predicate (lambda (x) (hash-has-key? *variable-table* x))))

    (let loop ((a '()) (L L))
      (if (null? L)
          (reverse a)
          (if (list? (car L))
              (loop (cons (let-helper (car L)) a) (cdr L))
              (if (predicate (car L))
                  (loop (cons (action (car L)) a) (cdr L))
                  (loop a (cdr L))))))

Untested.


So the swap should only occur if the hash has the key but the returned list should still have the elements that weren't swapped? If so then not removing the element from the list of it isn't a key would fix that like this:

(define (let-helper L)
  (map (lambda (x) 
         (if (list? x) 
             (let-helper x) 
             (if (hash-has-key? *variable-table* x) 
                 (swap x (hash-ref *variable-table* x) L) 
                 x))))
       L)

Or

(define (let-helper L)
  (let ((action (lambda (x) (swap x (hash-ref *variable-table* x) L)))
        (predicate (lambda (x) (hash-has-key? *variable-table* x))))

    (let loop ((a '()) (L L))
      (if (null? L)
          (reverse a)
          (if (list? (car L))
              (loop (cons (let-helper (car L)) a) (cdr L))
              (if (predicate (car L))
                  (loop (cons (action (car L)) a) (cdr L))
                  (loop (cons (car L) a) (cdr L))))))

Upvotes: 1

Related Questions