application: not a procedure drracket scheme [duplicate] - scheme

During the execution of my code I get the following errors in the different Scheme implementations:
Racket:
application: not a procedure;
expected a procedure that can be applied to arguments
given: '(1 2 3)
arguments...:
Ikarus:
Unhandled exception
Condition components:
1. &assertion
2. &who: apply
3. &message: "not a procedure"
4. &irritants: ((1 2 3))
Chicken:
Error: call of non-procedure: (1 2 3)
Gambit:
*** ERROR IN (console)#2.1 -- Operator is not a PROCEDURE
((1 2 3) 4)
MIT Scheme:
;The object (1 2 3) is not applicable.
;To continue, call RESTART with an option number:
; (RESTART 2) => Specify a procedure to use in its place.
; (RESTART 1) => Return to read-eval-print level 1.
Chez Scheme:
Exception: attempt to apply non-procedure (1 2 3)
Type (debug) to enter the debugger.
Guile:
ERROR: In procedure (1 2 3):
ERROR: Wrong type to apply: (1 2 3)
Chibi:
ERROR in final-resumer: non procedure application: (1 2 3)

Why is it happening
Scheme procedure/function calls look like this:
(operator operand ...)
Both operator and operands can be variables like test, and + that evaluates to different values. For a procedure call to work it has to be a procedure. From the error message it seems likely that test is not a procedure but the list (1 2 3).
All parts of a form can also be expressions so something like ((proc1 4) 5) is valid syntax and it is expected that the call (proc1 4) returns a procedure that is then called with 5 as it's sole argument.
Common mistakes that produces these errors.
Trying to group expressions or create a block
(if (< a b)
((proc1)
(proc2))
#f)
When the predicate/test is true Scheme assumes will try to evaluate both (proc1) and (proc2) then it will call the result of (proc1) because of the parentheses. To create a block in Scheme you use begin:
(if (< a b)
(begin
(proc1)
(proc2))
#f)
In this (proc1) is called just for effect and the result of teh form will be the result of the last expression (proc2).
Shadowing procedures
(define (test list)
(list (cdr list) (car list)))
Here the parameter is called list which makes the procedure list unavailable for the duration of the call. One variable can only be either a procedure or a different value in Scheme and the closest binding is the one that you get in both operator and operand position. This would be a typical mistake made by common-lispers since in CL they can use list as an argument without messing with the function list.
wrapping variables in cond
(define test #t) ; this might be result of a procedure
(cond
((< 5 4) result1)
((test) result2)
(else result3))
While besides the predicate expression (< 5 4) (test) looks correct since it is a value that is checked for thurthness it has more in common with the else term and whould be written like this:
(cond
((< 5 4) result1)
(test result2)
(else result3))
A procedure that should return a procedure doesn't always
Since Scheme doesn't enforce return type your procedure can return a procedure in one situation and a non procedure value in another.
(define (test v)
(if (> v 4)
(lambda (g) (* v g))
'(1 2 3)))
((test 5) 10) ; ==> 50
((test 4) 10) ; ERROR! application: not a procedure
Undefined values like #<void>, #!void, #<undef>, and #<unspecified>
These are usually values returned by mutating forms like set!, set-car!, set-cdr!, define.
(define (test x)
((set! f x) 5))
(test (lambda (x) (* x x)))
The result of this code is undetermined since set! can return any value and I know some scheme implementations like MIT Scheme actually return the bound value or the original value and the result would be 25 or 10, but in many implementations you get a constant value like #<void> and since it is not a procedure you get the same error. Relying on one implementations method of using under specification makes gives you non portable code.
Passing arguments in wrong order
Imagine you have a fucntion like this:
(define (double v f)
(f (f v)))
(double 10 (lambda (v) (* v v))) ; ==> 10000
If you by error swapped the arguments:
(double (lambda (v) (* v v)) 10) ; ERROR: 10 is not a procedure
In higher order functions such as fold and map not passing the arguments in the correct order will produce a similar error.
Trying to apply as in Algol derived languages
In algol languages, like JavaScript and C++, when trying to apply fun with argument arg it looks like:
fun(arg)
This gets interpreted as two separate expressions in Scheme:
fun ; ==> valuates to a procedure object
(arg) ; ==> call arg with no arguments
The correct way to apply fun with arg as argument is:
(fun arg)
Superfluous parentheses
This is the general "catch all" other errors. Code like ((+ 4 5)) will not work in Scheme since each set of parentheses in this expression is a procedure call. You simply cannot add as many as you like and thus you need to keep it (+ 4 5).
Why allow these errors to happen?
Expressions in operator position and allow to call variables as library functions gives expressive powers to the language. These are features you will love having when you have become used to it.
Here is an example of abs:
(define (abs x)
((if (< x 0) - values) x))
This switched between doing (- x) and (values x) (identity that returns its argument) and as you can see it calls the result of an expression. Here is an example of copy-list using cps:
(define (copy-list lst)
(define (helper lst k)
(if (null? lst)
(k '())
(helper (cdr lst)
(lambda (res) (k (cons (car lst) res))))))
(helper lst values))
Notice that k is a variable that we pass a function and that it is called as a function. If we passed anything else than a fucntion there you would get the same error.
Is this unique to Scheme?
Not at all. All languages with one namespace that can pass functions as arguments will have similar challenges. Below is some JavaScript code with similar issues:
function double (f, v) {
return f(f(v));
}
double(v => v * v, 10); // ==> 10000
double(10, v => v * v);
; TypeError: f is not a function
; at double (repl:2:10)
// similar to having extra parentheses
function test (v) {
return v;
}
test(5)(6); // == TypeError: test(...) is not a function
// But it works if it's designed to return a function:
function test2 (v) {
return v2 => v2 + v;
}
test2(5)(6); // ==> 11

Related

What is supposed to happen when a procedure's argument is given multiple values when it expects one value only?

(+ (values 1) (values 2)) returns 3. What is (+ 1 (values 2 3)) supposed to return? In R7RS-small, is the second value in a (values ...) automatically ignored when only one value is needed? In Guile 3.0.7, (+ 1 (values 2 3)) returns 3, but it gives an error in MIT Scheme 11.2 and Chibi 0.10.0.
(+ (values 1) (values 2)) is fine, and the result should be 3. But it is not the case that unneeded values are automatically ignored in a values expression; in fact the behavior of (+ 1 (values 2 3)) is unspecified in both R6RS and R7RS Scheme.
From the entry for values from R6RS 11.15 [emphasis mine]:
Delivers all of its arguments to its continuation....
The continuations of all non-final expressions within a sequence of
expressions, such as in lambda, begin, let, let*, letrec,
letrec*, let-values, let*-values, case, and cond forms,
usually take an arbitrary number of values.
Except for these and the continuations created by call-with-values,
let-values, and let*-values, continuations implicitly accepting a
single value, such as the continuations of <operator> and
<operand>s of procedure calls or the <test> expressions in
conditionals, take exactly one value. The effect of passing an
inappropriate number of values to such a continuation is undefined.
R7RS has similar language in 6.10:
The effect of passing no values or more than one value to continuations that were not created in one of these ways is unspecified.
The reason that (+ (values 1) (values 2)) is ok is that continuations of operands in procedure calls take exactly one value. (values 1) and (values 2) each provide exactly one value for their respective continuations.
call-with-values is meant for connecting producers of multiple values with procedures which consume those values. The first argument to call-with-values should be a procedure which takes no arguments and produces values to be consumed. The second argument should be a procedure which accepts the number of values produced by the first procedure:
> (call-with-values (lambda () (values 2 3))
(lambda (x y) (+ 1 x y)))
6
Note that the above use of call-with-values requires the consumer to accept the number of values produced by the producer since Scheme requires that implementations raise an error when a procedure does not accept the number of arguments passed to it:
> (call-with-values (lambda () (values 2 3 4))
(lambda (x y) (+ 1 x y)))
Exception: incorrect argument count in call (call-with-values (lambda () (values 2 3 4)) (lambda (x y) (+ 1 x y)))
If it is desirable for extra arguments to be ignored, the consumer must be designed towards that goal. Here the consumer is designed to ignore all but its first argument:
> (call-with-values (lambda () (values 2 3 4))
(lambda (x . xs) (+ 1 x)))
3

Trying to write a function that returns another function, but Racket says my lambda is not a function definition?

Programming in racket, I am trying to write a function that takes a single integer, and returns a function that increments that integer by another integer. For example:
((incnth 5) 3) --> 8
((incnth 3) -1) --> 2
Unfortunately I don't seem to understand lambda functions still, because my code keeps saying that my lambda is not a function definition. Here is what I wrote.
(define (incnth n)
(lambda (f) (lambda (x) (+ n x))))
You have one more lambda than it's needed. If I understand correctly, the idea is to have a procedure that creates procedures that increment a number with a given number. So you should do this:
(define (incnth n) ; this is a procedure
(lambda (x) (+ n x))) ; that returns a lambda
The returned lambda will "remember" the n value:
(define inc2 (incnth 2))
And the resulting procedure can be used as usual, with the expected results:
(inc2 40)
=> 42
((incnth 5) 3)
=> 8
((incnth 3) -1)
=> 2

evaluating my own functions from list with eval, R5RS

I am having problems with this
e.g. i have
(define (mypow x) (* x x))
and I need to eval expressions from given list. (I am writing a simulator and I get a sequence of commands in a list as an argument)
I have already read that R5RS standard needs to include in function eval as second arg (scheme-report-environment 5), but still I am having issues with this.
This works (with standard function):
(eval '(sqrt 5) (scheme-report-environment 5))
but this does not:
(eval '(mypow 5) (scheme-report-environment 5))
It says:
../../../../../../usr/share/racket/collects/racket/private/kw.rkt:923:25: mypow: undefined;
cannot reference undefined identifier
Eventhough simply called mypow in prompt returns:
#<procedure:mypow>
Any advice, please? (btw I need to use R5RS)
(scheme-report-environment 5) returns all the bindings that are defined in the R5RS Scheme standard and not any of the user defined ones. This is by design. You will never be able to do what you want using this as the second parameter to eval.
The report mentions (interaction-environment) which is optional. Thus you have no guarantee the implementation has it, but it will have all the bindings from (scheme-report-environment 5)
For completeness there is (null-environment 5) which only has the bindings for the syntax. eg. (eval '(lambda (v) "constan) (null-environment 5)) works, but (eval '(lambda (v) (+ 5 v)) (null-environment 5)) won't since + is not in the resulting procedures closure.
Other ways to get things done
Usually you could get away without using eval alltogether. eval should be avoided at almost all costs. The last 16 years I've used eval deliberately in production code twice.
By using a thunk instead of data:
(define todo
(lambda () ; a thunk is just a procedure that takes no arguments
(mypow 5))
(todo) ; ==> result from mypow
Now imagine you have a list of operations you'd like done instead:
(define ops
`((inc . ,(lambda (v) (+ v 1))) ; notice I'm unquoting.
(dec . ,(lambda (v) (- v 1))) ; eg. need the result of the
(square . ,(lambda (v) (* v v))))) ; evaluation
(define todo '(inc square dec))
(define with 5)
;; not standard, but often present as either fold or foldl
;; if not fetch from SRFI-1 https://srfi.schemers.org/srfi-1/srfi-1.html
(fold (lambda (e a)
((cdr (assq e ops)) a))
with
todo)
; ==> 35 ((5+1)^2)-1

How does a closure occur in this scheme snippet?

I'm having some trouble deciphering this code snippet.
(define (stream n f)
(define (next m)
(cons m (lambda () (next (f m)))))
(next n))
(define even (stream 0 (lambda (n) (+ n 2))))
I understand that 'even' is defined as a variable using the 'stream' function, which contains parameters 0 and '(lambda (n) (+ n 2))'. Inside of 'stream', wouldn't '(next n)' indefinitely create cons nodes with a car of n + 2? Yet when I return 'even', it is a cons of (0 . # < Closure>). Could someone be so kind as to explain why this is? Thanks!
Everytime (lambda ...) is evaluated it becomes a closure. What it means is that f is free and available for both procedures next and for the anonymous procedure it creates. m, which is a bound variable in next is also captured as a free variable in the anonymous procedure. If the language were dynamically bound none of them would exist if you called the resulting procedure in the cdr since the bindings would no longer exist, but since we have closures the variable exists even after the procedures that created them ended.
The pair returned by the stream procedure has references to the closure created when (lambda (n) (+ n 2)) was evaluated though the name f even though the call is finished. Thus if you do:
((cdr even)) ; ==>
(#<closure>) ; ==>
(cons 2 #<new-closure>) ; ==> Here
It's important to know that the evaluation of next becomes a pair with a new closure that has a new free variable m that is 2 this time. For each time you call the cdr it creates a new pair with a new closure. If it was the same each time you wouldn't have different result each iteration.
A lambda on it's own doesn't run the code in it's body. Thus instead of infinite recursion you only get one step and the result (cons 2 #<new-closure>). You need to call the cdr of this again ni order to get one more step. etc. Likewise if I did this:
(define (test a)
(define (helper b)
(+ a b))
helper) ; return the helper that has a as closure variable
Since we actually don't use the name one could just have anonymous lambda there instead of the define + the resulting variable. Anyway, you get something that gives you partially application:
((test 5) 2) ; ==> 7
(define ten-adder (test 10))
(ten-adder 2) ; ==> 12
(ten-adder 5) ; ==> 15

Keep getting procedure application: expected procedure, from this code

Im learning Scheme currently and have been tasked with writing something to count the length of a list, this is the code i currently have.
{define (len x)
(if(not(null? x))
(+ 1 len(cdr x))
(0))}
when run with '(2 3 4 5) it gives:
procedure application: expected procedure, given: '(2 3 4 5) (no arguments)
as an error. What am I doing wrong?
You have parentheses problems. Try this:
(define (len x)
(if (not (null? x))
(+ 1 (len (cdr x)))
0))
In particular, notice that:
When you're going to call a function, the function name (and the parameters, if any) must be surrounded by (). So len(x) is wrong, and (len x) is right
If something is not a function, then don't surround it with (). If you write (0), Scheme believes that 0 is a function and tries to apply it, which clearly is going to fail

Resources