Search code examples
racketdr.racket

Racket Error: Expected a procedure that can be applied to arguments


Sorry, I just started using racket. I'm pretty new at this. I've written this piece of code:

(define (save_sheets lst num)
  (if(= num (- (length lst) 1))
     ('())
     (
      (my_save_image (join_sheet (list-ref lst num)) num)
      (save_sheets lst (+ num 1)))))

Of course, when I run this I get this error:

application: not a procedure;
expected a procedure that can be applied to arguments
given: (object:image% ...)
arguments...: [none]

(join_sheet (list-ref lst num)) should return an image, which the error shows, but the my_save_image should take it in right? It's parameters is the image and a number. Thanks!


Solution

  • Remember that parentheses in Racket (and other Lisp-like languages) are not like parentheses in other languages… they are important! In many languages, there is no difference between x, (x), ((x)), and ((((x)))), but in Racket, these are all very different expressions.

    In Racket, parentheses mean function application. That is, (f) is like writing f() in other languages, so ((f)) is like writing f()(), and so on. This is important, since it means things like (3) are quite nonsensical in Racket—that would be like writing 3() in other languages, and 3 is definitely not a function.

    Now, let’s consider the problem you’re having. You are using if, which has the following grammar:

    (if conditional-expression then-expression else-expression)

    This means that each of the pieces of code inside the if must be valid expressions on their own. However, take a close look at your then-expression, which is ('()). This is kind of like the (3) example from earlier, isn’t it? '() is not a function, so it should not be surrounded in parentheses!

    Your else-expression exhibits a similar problem, but it is a little more complicated, since you seem to wish to run two functions there. If you want to run the first function for side-effects, you would not use parentheses alone for grouping, you would use begin, but it’s not clear to me if that’s what you actually want here or not. In any case, as-written, your program will attempt to apply the result of the call to my_save_image as a function, passing it the result of the recursive call to save_sheets as an argument, which is almost certainly not what you want.

    Mind your parentheses. In Racket, they are to be treated with care.