Question

I am trying to create a simple recursive function that takes a list, and applies the appropriate functions based on the element of the list. On input:

Input:  (myfunct '(plus ( minus(5 4) 3 ) )
Output: 4

So I check what the string is, then recursively solve the expression accordingly.

This is what I have right now (just for plus):

(define (myfunct lis)
    ((integer? (car lis)) (car lis))
    ((equal? 'plus (car lis)) (+ myfunct(car (cdr(lis)) myfunct(cdr(cdr lis)))))                                              
 )
 //if its an integer, return it
 //if its plus, call myfunct with the 2 next heads of the list

This produces the error (on input "(myfunct '(plus 4 5))":

application: not a procedure;
 expected a procedure that can be applied to arguments
  given: #f
  arguments...:
   plus

I can't pinpoint the reasoning for the error, could I please have an explanation/fix?

EDIT:

(define (myfunct lis)
  (cond  ((integer? lis) lis)
         ((integer? (car lis)) (car lis))
         ((equal? 'plus (car lis))
          (+ (myfunct (car (cdr lis))) (myfunct (cdr (cdr lis)))))))

Works with: (myfunct '(plus (plus 4 5) 6) However, it still will not work with... (myfunct '(plus (plus 4 5) (plus 2 3))). The second argument keeps coming back as void "()". I drew the recursive tree, and I can't see any reason for that error. Any ideas?

EDIT 2: Final working answer, not 100% sure why this works and not the other, my best guess is that the second argument was (at some point) ((plus 1 1)) instead of (plus 1 1), and the car on that would return the wrong value.

(define (myfunct lis)
  (cond  ((integer? lis) lis)
          ;;((integer? (car lis)) (car lis))
         ((equal? 'plus (car lis))
          (+ (myfunct (car (cdr lis))) (myfunct (cdr (cdr lis)))))
         (else (myfunct (car lis)))))
Was it helpful?

Solution

You have several problems with the parentheses (some are missing, some are misplaced, etc.) Use your IDE's tools for catching errors like this. In particular, the parentheses surrounding both lines in the body are wrong, because Racket thinks that you're trying to apply a procedure - this is why you're getting an application: not a procedure error:

  ((integer? (car lis)) (car lis))
  ^                              ^
wrong                          wrong

Besides that, you must use conditionals (if, cond, etc.) to distinguish between the different cases. And you're not processing the parts of each expression correctly, figure out how to access a list's first, second and third element.

I suggest you start by getting familiar with the syntax, write shorter, simpler procedures before tackling this exercise. I'll give you some hints to get you started, fill-in the blanks:

(define (myfunct lis)
  (cond ((integer? lis)
         lis)
        ((equal? 'plus <first element>)
         (+ (myfunct <second element>) (myfunct <third element>)))
        (<similarly for the 'minus case>)

If everything is correct, the sample input you provided should work as expected:

(myfunct '(plus 4 5))
=> 9
(myfunct '(plus (minus 5 4) 3))
=> 4
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top