I was trying to test a small portion of code and for some reason I have some errors. here is the code. here tab is just a function returning a list and translate is another function.
(define p
(let ((x (car tab)) (y (cadr tab)))
(list translate(x) y)))
A function call is written as (f args) where f is the name of the function and args a space-separated sequence of arguments.
So to call tab without arguments, you'd write (tab) and to call translate with the argument x, you'd write (translate x).
+ is a common procedure in Scheme and if you evaluate it will evaluate the symbol and you'll get a implementation dependent representation of the procedure object:
+ ; ==> <procedure: +> (or something similar)
Now + is just a variable that, when evaluated, evaluates to a procedure. How to call it is just to suround it with parentheses:
(+) ; ==> 0
What happens is that Scheme sees the parentheses, then evaluates the first argument + and it becomes the procedure <procedure: +>. Since it'a procedure the arguments are evaluated in any order and last the procedure is applied with those evaluated arguments.
If tab is a procedure object you cannot apply car or cdr to it. You can do it to the result of calling it if it evaluates to a pair. Likewise if you want to call a procedure translate with argumentx it needs to look like (translate x). Putting it all together:
(define p
(let* ((tab-result (tab))
(x (car tab-result))
(y (cadr tab-result)))
(list (translate x) y)))
Related
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
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
I found the following code about Higher Order Functions in Scheme:
(define make-double (lambda (f)
(lambda (x)
(f x x))))
(define square (make-double *))
For what I see make-double receives as an argument a function:f, and this function receives and x as argument. This argument x is doubled and make-double return the function f with this x value doubled. Is it like that?
The call to the function square is straightforward, just call the function make-double and the function *, but how can I run this program? When I execute it with:
square
It returns to me:
(lambda (x) (f x x))
How to interpret that? I suppose this function allowed to print an element twice, but maybe I am mistaken? Any help?
Try evaluating (square 42). :-)
Typing square just prints the value of square, which is a function.
(lambda (x) (f x x))
Tells you that square is a function accepting one argument, whose value will be used as both arguments of the function bound by f, which is in this case is *.
I wanna map a function which takes an argument:
(map best-play (cdr tree) true) ;true is the argument I wanna pass
Is it possible?
Yes. You can use a function called curry (or its sibling, curryr), which permits partial application, allowing you to pass in arguments without calling the function to yield a new function.
To understand that, consider this example.
> (define add2 (curry + 2))
> (add2 1)
3
> (add2 2)
4
Effectively, calling curry on + and passing a single argument creates a new function which is equivalent to this:
(lambda (x) (+ 2 x))
The function curryr is similar, but it passes arguments starting from the right, rather than the left. This is useful in functions where order matters.
> (define sub2 (curryr - 2))
> (sub2 4)
2
You can use these functions to perform the mapping you want. If the true argument comes second, then you'd want to use curryr, like this:
(map (curryr best-play true) (cdr tree))
I'm new to Scheme and was just curious about 'define'. I've seen things like:
(define (square x) (* x x))
which makes sense [Function name 'square' input parameter 'x']. However, I found some example code from the 90's and am trying to make sense of:
(define (play-loop-iter strat0 strat1 count history0 history1 limit) (~Code for function~)
Except for the function name, are all of those input parameters?
Short answer - yes, all the symbols after the first one are parameters for the procedure (the first one being the procedures's name). Also it's good to point out that this:
(define (f x y)
(+ x y))
Is just syntactic sugar for this, and both forms are equivalent:
(define f
(lambda (x y)
(+ x y)))
In general - you use the special form define for binding a name to a value, that value can be any data type available, including in particular functions (lambdas).
A bit more about parameters and procedure definitions - it's good to know that the . notation can be used for defining procedures with a variable number of arguments, for example:
(define (f . x) ; here `x` is a list with all the parameters
(apply + x))
(f 1 2 3 4 5) ; 0 or more parameters can be passed
=> 15
And one final trick with define (not available in all interpreters, but works in Racket). A quick shortcut for defining procedures that return procedures, like this one:
(define (f x)
(lambda (y)
(+ x y)))
... Which is equivalent to this, shorter syntax:
(define ((f x) y)
(+ x y))
((f 1) 2)
=> 3
Yes, strat0 through limit are the parameters of the play-loop-iter function.
The general form for define is:
(define (desired-name-of-procedure item-1 item-2 item-3 ... item-n)
(; what to do with the items))
Another way to explain the behaviour of define, is in terms of "means of combination", and "means of abstraction".
[A] The means of combination in simple terms:
The syntax (item-1 item-2 item-3 ... ... item-n) is the fundamental means of combination provided by Scheme (and Lisp in general.)
All code is a list represented using the above pattern
The very first (leftmost) item is always treated as an operator
Parentheses enforce the application of the operator... The leftmost item is required to accept all the items that follow, as arguments
[B] means of abstraction is simply; a way to name things.
An example will demonstrate how this all folds into the idea of the define primitive...
Example--Arriving at define in a bottom-up way
Consider this expression:
(lambda (x y) (* x y))
In plain English, the above expression translates to "Create a nameless procedure that accepts two arguments, and returns the value of the their product". Note that this generates a nameless procedure.
More accurately, in terms of means of combination, Scheme provides us the keyword lambda as a primitive operator that creates user-defined procedures.
The leftmost item--lambda--is passed items (x y) and (* x y) as arguments, and the operator-application rule forces lambda to do something with the items.
The way lambda is defined internally causes it to parse the list (x y), and treat x and y as arguments to pass to the list (* x y), which lambda assumes is the user's definition of what to do when arguments x and y are encountered. Any value assigned to x and y will be processed in accordance with the rule (* x y).
Enter, means of abstraction...
Suppose I wanted to refer to this type of multiplication at several places in my program, I might tweak the above lambda expression like this:
(define mul-two-things (lambda (x y) (* x y)))
define takes mul-two-things and the lambda expression as arguments, and "binds" them together. Now Scheme knows that mul-two-things should be associated with a procedure to take two arguments and return their product.
As it happens, the requirement of naming procedures is so very common and provides so much power of expression, that Scheme provides a cleaner-looking shortcut to do it.
Like #oscar-lopez says, define is the "special form" Scheme provides, to name things. And as far as Scheme's Interpreter is concerned, both the following definitions are identical:
(define (mul-two-things x y) (* x y))
(define mul-two-things (lambda (x y) (* x y))