creating a procedure which takes list as an argument - scheme

I am a newbie in scheme and I am trying to write a procedure which always finds a list's tail's first element. This is important in recursive calls.
Here is my procedure :
(define second (lambda (x) (car(cdr(x))))
and this is how i try to check it whether it runs correctly or not:
>(define x (list 1 2 3 4))
>(second x)
and this is the error :
procedure application: expected procedure, given: (1 2 3 4) (no arguments)
=== context ===
stdin::184: second
/usr/share/racket/collects/racket/private/misc.rkt:85:7
What might be the problem? Can you give me an inspiration? Is my definition of "second" wrong or what?
Thanks in advance.

There's an extra, unnecessary pair of parenthesis in your code. This fixes it:
(define second (lambda (x) (car (cdr x))))
To be clear, this was wrong: (cdr(x)). The correct form is: (cdr x). Remember, whenever you need to apply a function f to an argument x the correct way is: (f x).

Scheme uses S-expressions, so instead of car(x), you should use (car x). In your case, that means (car (cdr x)), not car(cdr(x)).

Related

Scheme: how to get first atom from list

I need help with one issue: I can't handle how to get the first atom from the list in SCHEME language. I think I should make a loop, something like "while" and compare each element on boolean (?atom) and print first matched item.
Unfortunately, It's difficult for me to handle scheme syntax.
Please, can you propose any solution for me?
define func ?atom:
(define (atom? x) (not (or (pair? x) (null? x))))
Recursion is not that different from the usual way yo solve problems - you just have to be careful and set some meaningful base cases. For instance, how would you solve this problem in Java? by traversing all the list, and stoping when either 1) we found the element that matches the condition or 2) there are no more elements. This is exactly what we need to do:
(define (first-atom lst)
(cond ((null? lst) #f) ; there are no more elements in the list
((atom? (car lst)) ; current element is an atom
(car lst)) ; return it
(else ; otherwise
(first-atom (cdr lst))))) ; look in the rest of the list
It works as expected:
(first-atom '((2) 42 (3)))
=> 42
(first-atom '((1) (2)(3)))
=> #f
In your question you have the definition to atom? that returns #t if the argument is an atom and #f otherwise.
The function should handle the empty list. eg. What should happen when you do this:
(first-atom '())
Thus you need to check if the argument is the empty list and return whatever you supposed to return when there are no atoms in the arguments. Then you'll have a else expression that handles the rest.
You can use first to get the first element to check if it is an atom and then return it or you recure with the rest of the list.
Now here is something very similar that finds the number of elements in a list:
(define (length lst)
(if (null? lst)
0 ; obviously a 0 length list
(+ 1 (length (cdr lst))))) ; obviously one plus whatever length the rest is
Imagine what happens if you do (length '(1 2)). It does (+ 1 (length '(2))) which again does (+ 1 (+ 1 (length '()))) which again does (+ 1 (+ 1 0)). Simple as that. All loops are recursive functions in Scheme.
You reference to while indicates you might be familiar with other programming languages. I knew C, C++, Pascal, perl, PHP, and Java when starting to learn Lisp and I suddenly realized all the languages I knew were only subtle dialects of one language, Algol. I wasn't learning my sixth language, but my second. Scheme doesn't have a while loop. It has recursion. you need to get a book and start at the first page as if you didn't know how to program at all as assimilation from Algol will point you in the wrong direction.

How do we pass two lists as the arguments of a function in Scheme?

How do we pass two lists as the arguments in defining a function? I mean the two lists are arbitary, and "a real list" will be pass as the parameters during the function execution..
Is it something like
(define checklist
(lambda (list1 list2)
(or (null? list1) (null? list2))
#and my other work here))
or
(define (checklist list1 list2)
(or (null? list1) (null? list2))
#and my other work here)
or
(define checklist
(lambda list1 list2)
(or (null? list1) (null? list2))
#and my other work here)
? I am sorry if its too basic.I've tried these but when I passed 2 lists to run the function,I got "wrong number of arguments passed" error.Thank you!
The third makes a rest argument list1 and returns the value of the global variable list2 or an error if it doesn't exist. But giving 3+ expressions to define is not legal so the third won't be accepted.
Since (define (checklist l1 l2) ...) is just fancy way of writing (define checklist (lambda (1 2) ...)) the two first examples are the exact same.
Note that (or x y z) will evaluate to the first true value and if you have expressions after it becomes dead code. If you were expecting to do something if or if not (or x y z) were true or not you need to use a conditional like (if (or x y z) something-expression something-else-expression)

I'm not sure what this code is trying to do

(define changeit (lambda (x) (* x x)))
(define changeall
(lambda (x)
(if (null? x)
'()
(cons (changeit (car x)) (changeall (cdr x))))))
(changeit 8)
(changeit 9)
(changeall '(2 14 10 8))
I'm not really sure what changeall is doing, can anyone help explain it?
EDIT: Here is the rest of the code
Although Oscar Lopez's comment sums up what is going on, this answer is a bit more detailed. changeit is simply the x^2 function. changeall is a function of one argument. If that argument is the empty list ((null? x)), the function returns the empty list. Otherwise, changeall calculates the square of the first element of its argument list ((car x)) and prepends it to the result of a call to changeall with the rest of its initial argument list ((cdr x)). This is a recursive function call. At some point, the argument list will be exhausted, that is, the argument will be the empty list, and changeall will return the empty list (the first case we considered). At this point, the recursion will stop.

trying to understand church encoding in Scheme

I'm trying to understand the whole principal of church encoding through Scheme. I think I understand the basics of it such as
Church numeral for 0
(define c-0
(lambda (f)
(lambda (x)
x)))
Church numeral for 1
(define c-1
(lambda (f)
(lambda (x)
(f x))))
... and continue applying the function to x N times.
Now my problem is just what does this all mean? If I take church-3 for example:
(define c-3
(lambda (x)
(lambda (f)
(f (f (f x))))))
What is this actually doing? I have only basic scheme knowledge as well but I don't even understand how to use the function? what is an example input using the c-3 function? is it just applying something 3 times like a loop?
You are right. c-3 in this case is a function, that takes 1 argument. And returns another function.
This other function takes a 1 argument function, and applies it to the first argument.
In this example, I'm calling c-3 with an argument of 3, this will return a function.
Then, I feed this function, another function, that add1 to x.
((c-3 3) (lambda (x) (add1 x)))
6
This will produce 6 as you see. It applies add1 to 3, 3 times. I know this is confusing. But you can
manually replace the arguments in the body of the function to understand it better. Wherever you see f, just replace that with (lambda (x) (add1 x)) And replace x with 3 (or any number).
This will work with any 1 argument function as long as the argument is of the correct type.

Writing a function that takes a function as an argument in Racket

This is a hw assignment that requires me to write a scheme function that takes a function(with two params) and a list as parameters, then returns a list where each consecutive pair of the elements of the list is replaced by the value of the function applied to these two elements.
For example - If the list has an odd number of elements, the last element is ignored. For example, (apply-to-pairs (lambda (x y) (+ x y)) '(3 9 5 8 2 4 7)) should return (12 13 6).
so far what I have got is:
(define (fn-name fn l)
(if (null? (cdr l))null
(cons
(fn((car l)(car (cdr l)))
(fn-name fn (cdr l))))))
However, im getting this error in Racket(DrRacket):
application: not a procedure;
expected a procedure that can be applied to arguments
given: 3
arguments...:
9
... and it highlights fn((car lst)(car (cdr lst))). I'm trying to find out how to handle the function parameter. Thanks for the help!
As you already did you just apply fn like you would with any primitives like +. However you have extra parenthesis around (car lst) and (car (cdr lst)) which means you expect first element to also be a procedure you call with the second element as it's only argument and then fn only get one argument (the result of that if 3, 5 or 2 happens to be procedures) Perhaps you instead wanted (fn (car lst) (cadr lst)) (I'm using shothand for car+cdr)
Your base case should check both l and (cdr l) for null since if either one is you are fnished. (Try calling it with (fn-name + '(5))). You can use special form or to do that like (or test1 test2).
Also notice that null is not usually a bound symbol in Scheme. You either need to define it (define null '()) or use '().
EDIT ABout too many results..
Notice that when you have applied the first round withe the first two elements of the list you recurse with a new l starting at the list except the very first element.. That means you then will process 9 and 5 in the next iteration instead of 5 and 8. To fix that you need to use cddr (cdr+cdr) instead of just cdr.

Resources