1

I am trying to call a reverse function I wrote (that works when called alone) inside another function, but it outputs incorrect results.

I'm writing a program to take the derivative, with respect to x, of a bivariate polynomial. I have a main function called poly_derx which will call my two helper functions reverse_list and mult_by_index.

(define (mult_by_index list_1)
  (if (null? list_1)
      list_1
      (map * list_1 (range (length list_1)))))

(define (reverse_list list_1)
  (if (null? list_1)
      list_1
      (append(reverse (cdr list_1)) (list (car list_1)))))

(define (poly_derx list_1)
  (if (null? list_1)
      list_1
      (reverse_list(cons (mult_by_index (car list_1)) (poly_derx (cdr list_1))))))

(poly_derx `( (1) (1 2 3) () (3)))

Again, my 3 functions work fine until I add the reverse_list in poly_derx. Also, I know there is a built in reverse but I face the same issue.

At this point, the only thing I know to do is try calling reverse at different points in the function but nothing I know of works.

Pika Supports Ukraine
  • 3,612
  • 10
  • 26
  • 42
  • Show the code that does not work. – Sylwester Apr 07 '19 at 18:52
  • maybe consider adopting the conventions of the language you're learning instead of bringing styles/habits from other languages – Mulan Apr 07 '19 at 18:56
  • @Sylwester this is the code that does not work –  Apr 07 '19 at 19:00
  • Ah. I though you meant it stopped working when you moved the definition from being a global procedure to be local to `poly_derx`. – Sylwester Apr 07 '19 at 20:07
  • 1
    Please don't make more work for other people by vandalizing your posts. By posting on Stack Overflow, you've granted a non-revocable right, under the [CC BY-SA 3.0 license](https://creativecommons.org/licenses/by-sa/3.0) for SO to distribute that content. By SO policy, any vandalism will be reverted. If you want to know more about deleting a post, please read more at [How does deleting work?](https://meta.stackexchange.com/q/5221) – iBug Apr 07 '19 at 22:15

1 Answers1

4

Your problem relies in that you reverse in the default case and it gets called for every sublists from end to beginning. Thus (poly_derx '(1 2 3)) becomes (reverse_list (cons res1 (reverse_list (cons res2 (reverse_list res3 (reverse_list '()))))). You need to only reverse the final result. You can do that with a helper:

(define (poly_derx list_1)
  (define (helper list_1)
    (if (null? list_1)
        list_1
        (cons (mult_by_index (car list_1)) (helper (cdr list_1)))))

  (reverse_list (helper list_1)))

Also since lists are created from end to beginning and iterated from beginning to end you can use that to reverse lists in the helper.

(define (poly_derx list_1)
  (define (helper list_1 result)
    (if (null? list_1)
        result
        (helper (cdr list_1) (cons (mult_by_index (car list_1)) result))))

  (helper list_1 '()))

So make note that you cannot apply a procedure you would like to happen once for each iteration. It will give unexpected results.

Sylwester
  • 47,942
  • 4
  • 47
  • 79
  • So, I thought that it would not call the reverse until the function in its argument was completed. –  Apr 07 '19 at 21:53
  • @BobDole It doesn't discriminate between calling itself or calling something else. Everything in the `if` then or else expressions is done fully. – Sylwester Apr 07 '19 at 23:17