I AM LUNA
I AM LUNA

Reputation: 1

application: not a procedure; expected a procedure that can be applied to arguments (Scheme)?

application: not a procedure; expected a procedure that can be applied to arguments given: 1 arguments...: I am given this error when trying to run this program on DrRacket. Language: Scheme. My input was: (length '(A B (C D) E)) I am trying to return the length of the list. It is suppose to return 4.

#lang scheme
(define (length list)
    (cond((null? list) 0)
       (else
          (+1 (length (cdr list))))))

Upvotes: 0

Views: 328

Answers (2)

Sylwester
Sylwester

Reputation: 48745

TL;DR: You need to have a procedure in the operator place:

(+ 1 (length (cdr list))) ; notice the vital space between the symbol + and the number 1

Longer explanation:

Scheme evaluates the operator eg. the global variable + evaluates to a procedure object that adds it arguments together so with parentheses, eg. (+ a b) evaluates the variables +, a, and b and then apply the expected procedure object behind +.

1 and +1 are both the literal for a fixnum positive one. You can prefix all positive numbers with + and the parser will not do anything different.

Thus the expression (+1 (length (cdr list))) evaluates +1 to the positive number one and (length (cdr list)) to 0 (since a one element list is the first application that gets evaluated), however when Scheme tried to apply it will fail since the number is not a procedure.

In Racket you get the proper error message:

; application: not a procedure;
;  expected a procedure that can be applied to arguments
;   given: 1

1 here is because the parser sees the +1 and turns it into the number 1, but the error never sees how the number is written in the source code. There is lots of ways to write one specific number, but it will only display the number in one way.

1+ and 1- are perfectly and well defined functions in Common Lisp and they increment or decrement the argument, they are not defined in Scheme. You can:

(define (1+ v)
  (+ v 1))

(define (1- v)
  (- v 1))

;; test
(1+ 4) ; ==> 5
(1- 4) ; ==> 3

In Racket they are defined by different names:

(add1 4) ; ==> 5
(sub1 4) ; ==> 3

Other things

Don't use #lang scheme. Racket used to be a super set of R5RS Scheme, but it is no longer that. #lang scheme is still just a synonym for #lang racket and it is no longer compatible with the Scheme language and you have no guarantee it will work in future versions of Racket. Use #lang racket instead of #!r5rs, #!r6rs, or #!r7rs if you rather use standard Scheme.

Upvotes: 1

Óscar López
Óscar López

Reputation: 235984

It's a simple mistake, there must be a space between the + and the 1, that's how we apply a function in Scheme. For example, this is wrong:

(+1 41)

And this is correct:

(+ 1 41)

Fixing your procedure:

(define (length list)
  (cond ((null? list) 0)
        (else (+ 1 (length (cdr list))))))

Upvotes: 2

Related Questions