Please Help Me Understand Scheme: No Arguments? - syntax

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.

Related

Are there any default arguments for procedures if they have only one?

Could someone explain the following expression
> (+)
0
> (+ 1)
1
> (- 1)
-1
> (/ 1)
1
> (/ 2)
1/2
> (/ 3)
1/3
If there is a default argument of 1, why does (+ 1) return 1 while (/ 2) return 1/2 ?
Shouldn't (+ 1) return 2 ?
For + and * the implicit default first argument is the identity element for the mathematical operations they represent, which are the addition and multiplication operations over various number fields. For + this is 0 which is the identity element for the group of addition over numbers; for * this is 1 which is the identity element for multiplication over numbers.
So
(+) is (+ 0) is 0;
(+ 1) is (+ 0 1) is 1;
(*) is (* 1) is 1;
(* 2) is (* 1 2) is 2.
For - and / the implicit default arguments are the appropriate identities of the operations that these are the inverses of as well, although these functions require at least one argument, and their behaviour with more than one argument is not quite as simple.
So
(-) is an error (I don't see why it should not be 0);
(- 1) is (- 0 1) is -1;
(- 1 2) is not (- 0 1 2);
(/) is an error (I don't see why it should not be 1);
(/ 2) is (/ 1 2) is 1/2;
(/ 3 2) is not (/ 1 3 2).
To be really precise, in the Scheme context, the default arguments are the exact numbers representing the identities I think.
Note that these default arguments are just chosen for mathematical convenience: this is not something inherent in the design of the language. I could define a language where (+) was "foo", although it would probably not be a very useful language.
If there are default argument 1, why (+ 1) return 1 ...
Look carefully. For +, the "default argument" is actually 0 (and not 1 as you claim):
> (+)
0
This is exactly what the documentation says about +:
... If no arguments are provided, the result is 0.
Then when you add 1 to 0, you get 1:
> (+ 1)
1
(Note: If you want to add 1 to a number, use add1. e.g. (add1 1) -> 2)
For a variadic procedure (i.e. a procedure that can take a variable number of arguments), the "default argument" depends on how the procedure was implemented. For example, if you define a variadic procedure using (define (f . arglist) ...), the implicit default argument depends on how the body of the procedure makes use of arglist.
You should understand the reduce and fold operations. + and - can be expressed as reductions, but in reductions you explicitly see the value for empty set of operands.

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 - syntax with if statements

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.

define quote process in racket?

I have this couple of lines that I'm running on drracket,
I can't understand the output
> (define 'a 5)
> 'b
. . ..\..\Program Files\Racket\share\pkgs\drracket\drracket\private\rep.rkt:1088:24: b: undefined;
cannot reference an identifier before its definition
> '0
5
is quote redefined?
why 'b isn't working and '0 is 5?
First, symbols are atomic values. They cannot be treated like variables.
Anyway, your first line expands to:
(define (quote a) 5)
which is shorthand for defining functions in racket. So yes, you are redefining quote.
When you try to run 'b, you're running (quote b), where it expects a variable b to have some value, which is does not. That's why you receive the error, cannot reference an identifier before its definition.
When you try to run '0, you're running (quote 0). 0 is a valid value, and it becomes the value for a in your new function. So, the function evaluates as normal, and returns 5.
In other words, it's not just 0 that is a valid argument.
> (define 'a 5)
> (define b 12345)
> 'b
5
> '0
5
> '123454321
5
Check out the Racket documentation on symbols. Symbols don't contain values; they are values. You'll want to use variables instead ((define a 5)).

How to convert this code to Scheme

So basically this code's purpose is to simply print out the first n even numbers.
for (i = 0; i <=n; i+= 2)
{
print i;
}
Thing is though, I don't understand Scheme at all. So, help please.
There are several ways to convert the code in the question to Scheme. The first one I can think of:
(define (print-even n)
(let loop ((i 0))
(if (<= i n)
(begin
(print i)
(newline)
(loop (+ i 2))))))
Notice this:
The solution is written as a recursive procedure
Instead of a for loop, I'm using a construct called a named let, which permits the initialization of some iteration variables (i in this case, initialized to 0) and the repeated execution of a recursive procedure (loop in this case), producing an effect similar to a for, even in performance
The stop condition in the "loop" is handled with essentially the same expression: repeat the body of the iteration as long as (<= i n), when that condition becomes false, the iteration ends
The begin surrounds the body of the "loop", just as the curly braces {} do in the original code
The print procedure performs the expected operation; for readability I added a new line after printing each number
The increment part of the original loop i += 2 is handled by the expression (+ i 2), inside the recursive call
So you see, the process being executed is essentially the same, only the way to write it (the syntax!) is different. Give it a try, type this:
(print-even 6)
... And the following will get printed on the screen:
0
2
4
6
Another possible way to implement the procedure, more similar to the original code, although (this is completely subjective) less idiomatic than the previous one:
(define (print-even n)
(do ((i 0 (+ i 2))) ((> i n))
(print i)
(newline)))
Finally, if you're using Racket this will seem even more familiar to you:
#lang racket
(define (print-even n)
(for ((i (in-range 0 (+ n 1) 2)))
(print i)
(newline)))
The first big difference between Scheme and other languages is this: In Scheme, you do (almost) everything recursively.
To implement a simple loop, for instance, you would define a recursive function. This function would first check to see whether it's time to break out of the loop; if is is, it would return the final value. (There is no final value in this case, so it would just return something like (void) or '().) Otherwise, the function would do whatever it's supposed to do, then call itself again.
Any loop variables (such as i) become arguments to the function.
Hopefully this helps you understand how to do this.
The Scheme way to do something like this is using a recursive function like the one below.
(define (doit value n)
(if (<= value n)
(begin
;;...perform loop body with x...
(display value)(newline)
(doit (+ value 2) n))))
To call this function you call (doit 2 n) where n is your n in the for loop.
With regards to learning Scheme, I recommend the first two links below.
For additional information on Scheme see
SICP
How to Design Programs
Schemers
Related Stackoverflow Question
Scheme Cookbook Looping Constructs

Resources