Scheme - syntax with if statements - scheme

Can anyone explain why this isn't working? I am following the documentation and I cannot understand why I get an error:
(define (functionName n)
(if (n < 10) ;;if condition
1 ;; then condition
3)) ;; else condition
I get the error:
application: not a procedure;
expected a procedure that can be applied to arguments
given: 5
arguments...:
#<procedure:<>
10

You can see this in two ways. Your code is correct and you just called it wrong (bad type for n) or your code was accidentally written in infix notation. I'll illustrate both:
Passed wrong argument
n can be any data type and it can even be a procedure and if it is there is nothing wrong with your code:
(define (compare-15 predicate-procedure argument)
(predicate-procedure 15 argument))
(define (compare-2 predicate-procedure argument)
(predicate-procedure 2 argument))
(functionName compare-15) ; ==> 3
(functionName compare-2) ; ==> 1
What happens is that your procedure is calling the supplied procedure with a procedure for comparing < and an argument.
Accidental infix
Algol programmers are used to prefix fun( expr ) and infix x cmp y while in LISP dialects all those have one common form and that is prefix all the way: (fun expr) and (cmd x y).
(define (function-name n)
(if (< n 10) ;; predicate expression
1 ;; consequent expression
3)) ;; alternative expression
(function-name 15) ; ==> 3
(function-name 2) ; ==> 1
Since Scheme can have functions as argument, meaning every argument can be put in the first position, it might be exactly what you wanted and Scheme doesn't know until it gets a number to be called as a procedure that something is wrong.
The error message is quite clear when you know that every procedure call is called application. It expected to call a procedure but behind the variable n there was a number. "expected a procedure that can be applied to arguments. given: 5" probably makes more sense now?

Try this:
(define (functionName n)
(if (< n 10)
1
3))
Remember: Scheme uses prefix notation, meaning that all operators must go before the operands. In other words, this is wrong: (n < 10), and this is correct: (< n 10).

The function should be the first thing in the if (scheme uses prefix notation, not infix).
(define (functionName n)
(if (< n 10) ;;if condition
1 ;; then condition
3)) ;; else condition
Then
(functionName 2)
Outputs
1
when I run it in Chicken Scheme.

Related

How to create a lambda procedures?

I need to complete an assignment for my college course using Scheme. I've never coded in Scheme before so I have no clue what I'm doing. Our assignment is to define an anonymous function that computes the discriminant of a quadratic function. I keep running into the error: "Invalid `define'. Any help would be appreciated.
(define roots (lambda(abc))(
(lambda(discriminant))(
list(/(+(-b) discriminant)(*2a))
(/(-(-b) discriminant)(*2a))
)
(sqrt - (*bb)(*4ac))
)
First, you should learn a bit about what Scheme code looks like; find some example code (in your textbook, or online, or in answers here on SO) and notice how parentheses and whitespace are used. Then emulate that. You can't arbitrarily place parentheses or arbitrarily remove whitespace in Scheme (or in any Lisp).
For example, in the posted code (-b) gets two things wrong. First, -b is treated as one symbol, not as the negation of the value of b. Further, placing the symbol in parentheses indicates a procedure call; given an s-expression (f x), f is either a syntactic keyword (in which case (f x) is interpreted as a macro call), or (f x) is interpreted as a procedure call. If it is a procedure call and f is not bound to a procedure, then an exception is raised. So (-b) attempts to call a procedure named -b, which does not exist (unless you have defined it), raising an exception. You can use (- b), with a space between the - procedure and the symbol b; this evaluates to the negation of the value of b.
Similarly, *2a is interpreted as a symbol, not an expression; placing the *2a between parentheses is interpreted as a procedure call. The interpreter (or compiler) is expecting that *2a is a procedure which takes no arguments. You need to add the spaces: (* 2 a); this is interpreted as a call to the procedure * with the arguments 2 and a.
(*bb) and (*4ac) have exactly the same problems. The second case is interesting because when it is correctly written it illustrates one of the advantages of prefix notation. Since * is associative, it does not matter what order multiple values are multiplied in. To express naively 4 * a * c in prefix notation you could write (* 4 (* a c)), explicitly ordering the multiplications. You could also write this as (* (* 4 a) c), multiplying in a different order. It does not matter what order you multiply in, so you might as well just write (* 4 a c), so long as your language supports this notation. It turns out that Scheme and other Lisps do support this notation.
Another problem with s-expression notation in the posted code (after fixing the problems noted above): (sqrt - (* b b) (* 4 a c)). This is attempting to call the sqrt procedure on the arguments -, (* b b), and (* 4 a c). But sqrt is not a higher-order procedure (i.e., it does not take procedures as arguments), and it in fact only takes one argument. It was meant to apply the - procedure to the arguments (* b b) and (* 4 a c), subtracting them before taking the square root: (sqrt (- (* b b) (* 4 a c))).
The first lambda expression has a formal parameter list containing only one parameter: abc. As before, this is a mistake. The intention was to define three parameters: don't skimp on spaces: (lambda (a b c)).
The other significant problem is that there are syntax errors in the lambda expressions: (lambda (a b c)) has no body, but a lambda expression must have at least one expression in its body. This was probably intended to wrap the lambda expression which follows. Similarly, the inner lambda expression is missing its body. It was probably intended to wrap the (list ;;...) form that follows.
With that done, the inner lambda expression is itself inside of a pair of parentheses, taking the expression (sqrt (- (* b b) (* 4 a c))) as its argument. This is the lambda form of a let binding. Thus, the inner lambda takes one argument, discriminant, and evaluates the list form that is its body. Since the inner lambda expression itself occurs in the first position of an s-expression, it is part of a procedure call, and this inner anonymous procedure is then called on its argument, binding discriminant to the value obtained by evaluating that argument, which is (sqrt (- (* b b) (* 4 a c))). This all occurs inside of the outer lambda, which takes the three arguments a, b, and c. So, root is a function taking three arguments, and returning a list of roots, after binding the result of the discriminant calculation to discriminant (as a way of both simplifying the expression of the roots and ensuring that the discriminant need only be calculated one time).
Here is the fixed-up code. Note that I only added some spaces and added or moved a few parentheses; nothing else was changed:
(define roots
(lambda (a b c)
((lambda (discriminant)
(list (/ (+ (- b) discriminant) (* 2 a))
(/ (- (- b) discriminant) (* 2 a))))
(sqrt (- (* b b) (* 4 a c))))))
Pay attention to what this looks like. In Lisps you should almost never leave parentheses hanging on lines by themselves, and you should always place a space between arguments. Remember that everything is a procedure call.
Here is a sample interaction. Notice that you can represent negative numbers as -1 instead of (- 1) (you can do either if you wish). You just can't express a negative value using a variable as -b.
> (roots 1 0 -1)
(1 -1)
> (roots 1 8 15)
(-3 -5)

How to write functions of functions in Scheme

I am supposed to write a function called (nth-filtered f n), where f is a function of one variable and n is a natural number, which evaluates to the nth natural number such that f applied to that number is #t.
If we called
(nth-filtered even? 1) we would get 2
(nth-filtered prime? 10) we would get 29
How do I make it so that it works for any sequential function? What should I think about when approaching this type of problem?
A variable is a variable and + is also a variable. The main difference between a function and some other data type is that you can wrap a function name in parentheses with arguments and it will become a new value.
eg.
(define (double fun)
(lambda (value)
(fun (fun value))))
(define (add1 v)
(+ 1 v))
(define add2 (double add1))
(add2 1) ; ==> 3
Now the contract doesn't say so you deduct by looking that you do (fun ...) that fun needs to be a function. Imagine this:
(define test (double 5)) ; probably works OK
(test 1)
The last one fails since you get application: 5 is not a procedure or something similar. The error message is not standardized.
How to attack your task is by making a helper that has the same arguments as your function but in addition the current number that I guess starts at 1. As I demonstrated you use the function variable as a function and recurse by always increasing the number and reducing n when the f call was #t. The actual function will just use the helper by passing all the parameters in addition to your state variable.
Your problem requires a fold, which is the standard way to iterate other a list while keeping a record of things done so far.
Here a very rackety method using for/fold:
(define (nth-filtered predicate index)
(for/fold ([count 0]
[current #f] #:result current)
([n (in-naturals 1)]) ; we start at 1 but we could start at 0
#:break (= count index)
(values (if (predicate n) (add1 count) count)
n)))
for/fold takes a list of initial state. Here we define count as the number of times the given predicate returned #t and current as the currently tested value.
Then it takes a list of iterators, in this case we only iterate infinitely over (in-naturals).
To make it stop, we provide a #:break condition, which is "when the number of truthy predicates (count) is equal to the requested amount (index)".
for/fold requests that it's body finishes with a list of values for each "state" variable, in order to update them for the next iteration. Here we provide two values: one is the new count, the other is just the current n.
You can try it out, it works as you requested:
> (nth-filtered even? 1)
2
> (require math/number-theory)
> (nth-filtered prime? 10)
29
> (nth-filtered prime? 5)
11

Scheme "Not a function" error

I am learning Scheme and I keep getting this error: "Error: 20 is not a function" from the following code:
(define myFunction (lambda (x y)
(* x y)))
(define (higherOrder func x y)
(
func x y))
(display ((higherOrder myFunction 4 5)))
I am trying to pass a function as one of the arguments. It goes through with the math since it says "20" in the error message and (5 * 4 = 20) but then it thinks it is a function. What is the problem? I cannot figure it out. I am running this code on https://repl.it/languages/Scheme.
You have one too many pairs of parens, the expression (higherOrder myFunction 4 5) evaluates to the integer 20, then the repl tries to evaluate (20), which it can't because 20 isn't a function. When Scheme evaluates a list (where a list is anything in parens that isn't quoted) the first entry in the list is assumed to be a function.
Change the last line to
(display (higherOrder myFunction 4 5))

Unable to evaluate a lambda expression as argument in SICP ex-1.37

The problem can be found at http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-12.html#%_thm_1.37
The problem is to expand a continuing fraction in order to approximate phi. It suggests that your procedure should be able to calculate phi by evaluating:
(cont-frac (lambda (i) 1.0)
(lambda (i) 1.0)
k)
My solution is as follows:
(define (cont-frac n d k)
(if (= k 1) d
(/ n (+ d (cont-frac n d (- k 1))))))
This solution works when calling (cont-frac 1 1 k), but not when using the lambda expressions as the problem suggests. I get what looks like a type error
;ERROR: "ex-1.37.scm": +: Wrong type in arg1 #<CLOSURE <anon> (x) 1.0>
; in expression: (##+ ##d (##cont-frac ##n ##d (##- ##k 1)))
; in scope:
; (n d k) procedure cont-frac
; defined by load: "ex-1.37.scm"
;STACK TRACE
1; ((##if (##= ##k 1) ##d (##/ ##n (##+ ##d (##cont-frac ##n ##d ...
My question is two-part:
Question 1. Why am I getting this error when using the lambda arguments? I (mistakenly, for sure) thought that (lambda (x) 1) should evaluate to 1. It clearly does not. I'm not sure I understand what it DOES evaluate to: I presume that it doesn't evaluate to anything (i.e., "return a value" -- maybe the wrong term for it) without being passed an argument for x.
It still leaves unanswered why you would have a lambda that returns a constant. If I understand correctly, (lambda (x) 1.0) will always evaluate to 1.0, regardless of what the x is. So why not just put 1.0? This leads to:
Question 2. Why should I use them? I suspect that this will be useful in ex-1.38, which I've glanced at, but I can't understand why using (lambda (x) 1.0) is any different that using 1.0.
In Scheme lambda expression creates a function, therefore expression such as:
(lambda (i) 1.0)
really does have result, it is a function object.
But if you add parentheses around that expression, it will indeed be evaluated to 1.0 as you expected:
((lambda (i) 1.0))
Using of lambdas in that exercise is necessary for building general solution, as you've correctly noticed in exercise 1.38, you'll be using the same implementation of cont-frac function but with different numerator and denominator functions, and you'll see an example, where you should calculate one of them in runtime using loop counter.
You could compare your exercise solutions with mine, e.g. 1.37 and 1.38
(/ n (+ d (cont-frac n d (- k 1))))))
In this case 'd' being the lambda statement, it doesn't make any sense to '+' it, same for 'n' and '/' try something like
(/ (n k) (+ (d k) (cont-frac n d (- k 1))))))
you'll see why in the next exercise you can also make this tail-recursive
I named my variables F-d and F-n instead of d and n, becuase they accept a function that calculates the numerator and denominator terms. (lambda (i) 1.0) is a function that accepts one argument and returns 1.0, 1.0 is just a number. In other continued fractions, the value may vary with the depth (thus why you need to pass k to the numerator and denomenator function to calculate the proper term.

Please Help Me Understand Scheme: No Arguments?

First time stackoverflow user but occasional lurker, hope you guys can help me out.
So the first part of my assignment is to drop all 'leading zeros' in a list.
ex: (0 0 0 0 0 1 0 1 0 1) -> (1 0 1 0 1)
To do this, I thought to use an IF statement to check whether the first element was a 0 or not, and to recursively call the rest of the list until the there were no more leading zeros. As I have basically no idea how to program in Scheme, through searching the internet, I came up with what you see below. However when I run it, DrRacket tells me there are no arguments- I assume this either a syntactical error.. or more likely, I have no idea what I'm doing. So, if you could help me out, I'd really appreciate it!
>(define zz
> (lambda (n)
> (if (= (car (n)) 0)
> (zz (cdr (n)))
> ((n)))))
>
>(remove '(0 0 0 0 1 0 1 0))
The error I get in DrRacket is:
"procedure application: expected procedure, given: (0 0 0 0 1 0 1 0) (no arguments)"
Again, thanks a lot! (P.S. Sorry if the formatting is a little odd...)
EDIT
Okay, changing up some stuff, I now get a "expects type as 1st argument, given: (0 0 0 0 0 1 0 1 0); other arguments were: 0" error flagged at my if statement.
>(define zz
> (lambda n
> (if (= (car n) 0) <----- here
> (zz(cdr n))
> (n))))
EDIT 2
>(define zz
> (lambda (n)
> (if (= (car n) 0)
> (zz (cdr n))
> n)))
It works, thank you very much!
(num) is not correct - you're trying to call 42 or whatever as a command. (Also, your if syntax is off; you may want to do read more code to get a better feel for the syntax).
This should compile:
(define remove
(lambda (num)
(if (= (car num) 0)
(remove (cdr num))
num)))
Parenthesis in Lisp are for calling functions, unless used in quotes.
Okay, the OP asked about a general rundown of the syntax for Scheme.
a - A symbol, which is looked up by the evaluator and substituted for its value. Some symbols (such as 42) evaluate to themselves.
'a - This "quotes" the symbol and transforms it into (quote a). quote prevents its argument from being evaluated - instead, the value a is returned. Not the string "a", not the result of looking up a, a itself. This also works for lists ('(1 2 3))
(if <expr> <true-value> <false-value>) - This evaluates <expr>, and sees if its value is truthy or not, and executes the corresponding value.
(cond (<expr> <true-value>)
...
(else <false-value>)) - This runs though its arguments, and evaluates the car of it to see if it is true. If it is, the value of evaluating the cdr is returned. Otherwise, it skips to the next value.
(define <name> <expr>) - Sets the value of evaluating the second argument to the name of the first argument.
(lambda <arg-list> <body>) - Creates a procedure which is the result of binding the arguments passed in to the names present in the second argument and evaluating the third argument.
(<func> <arg1> <arg2> ... <argn>) - If the evaluator finds out that none of the above patterns match, then it calls the car of the list as a function, with the arguments in the cdr.

Resources