0

I am trying to build a procedure to compare two lists (that are elements of a larger list) and return how similar they are. The procedure will do this by summing the difference between the elements in the same index in both lists. This is done recursively by comparing the car of both lists, calling on itself again with the running result being the comparison and the new lists being the cdr of both lists, and finally returning the result when both lists are empty. However, when I test this, the following error is returned even though I have an if statement to return the result when the lists are null:

Cannot read property 'car' of undefined [ ]

I'm fairly certain that my let syntax is correct, as that was fixed in a prior question, and the only other time car is used in the other procedure used doesn't have any errors when run by itself. What is happening and how can it be fixed?

Code:

(define (get-list name arr)
  (if (eq? name (car (car arr)))
      (cdr (car arr))
      (get-list name (cdr arr))))
(define (similarity-arrays name1 name2 arrs result)
  (let ((arr1 (get-list name1 arrs))
        (arr2 (get-list name2 arrs)))
    (if (= (length arr1)(length arr2))
        (let ((x1 (car arr1))
              (x2 (car arr2)))
          (if (null? arr1))
              result
              (similarity-arrays
               (cdr arr1)
               (cdr arr2)
               (+ result (- x1 x2)))))
        #f))
(define dust
  (list (list 'akko 11 3 7 5 4 1 9 8 10 6 2)
        (list 'Jodast 10 7 4 6 5 1 11 9 8 3 2)

(similarity-arrays 'Jodast 'Akko dust 0)
Rainer Joswig
  • 136,269
  • 10
  • 221
  • 346
Jodast
  • 1,279
  • 2
  • 18
  • 33

1 Answers1

4

There are several issues with your code. For instance:

  • The (if (null? arr1)) expression is an if with no consequent or alternative, because the rightmost ) must not be closed there, only after the consequent and alternative.
  • The recursive call to similarity-arrays is incorrect, you're passing the wrong type of parameters and the number of parameters is also incorrect.
  • Related to the previous one: both in get-list and similarity-arrays sometimes you assume that the parameters are elements and other times that they're lists
  • There are other parts with unbalanced brackets, for example, in the definition of dust. Use a good IDE and properly indent the code to show you where the parentheses are missing
  • We should try to avoid using length, the way to find out if we've reached the end of a list if by asking it it's null?.
  • For this problem you should use equal? for testing equality, not eq?.
  • Passing a list of two lists makes iteration harder, have you considered passing two lists instead?
Óscar López
  • 232,561
  • 37
  • 312
  • 386
  • I don't have access to a good IDE like bracket, I'm on a chromebook and my only option is repl.it which doesn't support indentation – Jodast May 29 '19 at 17:11
  • 1
    That's too bad :( Racket would make your life soo much simpler. – Óscar López May 29 '19 at 17:16
  • about the 3rd point, what do you mean and how do I fix it? about the 4th point, where are the unbalanced brackets? about the 5th point, I'm using `length` not to test if i've reached the end of the list, but rather to make sure that the lengths are the same. about the last point, what do you mean? – Jodast May 29 '19 at 17:18
  • 1
    3rd point: the first time you call both functions `name1` and `name2` are symbols, all the other times you're passing a list. Check your logic. – Óscar López May 29 '19 at 17:21
  • 1
    4th point: you opened a parentheses but either forgot to close it or closed it in the wrong place. Use an IDE, there's no better way. – Óscar López May 29 '19 at 17:22
  • 1
    5th point: you only have to check for length _once_, not every time in the recursion. Even better: _never_ check for length, just use `null?` to know when the lists are over. – Óscar López May 29 '19 at 17:23
  • 1
    7th point: your `dust` parameter is a list with two lists as elements, you'll have a hard time traversing it (in fact, in your code you don't have this correctly). Instead, why don't you pass two parameters, one with each list? – Óscar López May 29 '19 at 17:24
  • 1
    There are just too many issues with your code, sorry but I can't fix it. The fact that you're not using a good IDE is making things unnecessarily hard. Please spent more time studying Scheme's syntax and try to tackle simpler problems first, your code in its present form is a long way from being correct :( – Óscar López May 29 '19 at 17:26
  • as for the 7th point, in my actual code I have 8 other lists in `dust`, I just removed them to provide a minimal, verifiable answer – Jodast May 29 '19 at 19:13
  • 3rd point: I see the error now, the point originally was to get a list from `dust` based on a name. – Jodast May 29 '19 at 19:16
  • 1
    To get an idea about how to iterate over multiple lists at the same time, take a look at this [post](https://stackoverflow.com/a/17636016/201359), just replace `one-map` with the regular built-in `map`. – Óscar López May 29 '19 at 19:20
  • I see now that that is a better option. It's been a while since I read that part of sicp – Jodast May 29 '19 at 20:05