How does this define work? - scheme

I have this piece of scheme code:
(define (x . y) y)
(x 1 2 3)
and I know it equivalent to:
'(1 2 3)
But i can't understand why.
What does the first line of code do?
Thank you.

The first line (define (x . y) y) is equivalent to (define x (lambda y y)), according to 5.2 Definitions(the last clause).
And (lambda y y) is a procedure; when called all the arguments will stored in a newly allocated list. e.g. list could be defined as (define list (lambda xs xs)). (See 4.1.4 Procedures the second form of formal parameters.)
So (x 1 2 3) is equivalent to (list 1 2 3).

Related

dont understood lambda expression on scheme

i try to realize what this expiration, and don't get it.
( lambda (a b) (lambda (x y) (if b (+ x y a) (-x y a)))
i think,
a is a number, and b is #t or #f,
on the if statement we ask if b is true, if yes return first expression(sum 3 numbers), else the second(Subtract 3 numbers)
what i need to write on Racket to run this?
i try
(define question( lambda (a b) (lambda (x y) (if b (+ x y a) (-x y a)))))
and than
(question 5 #f)
and nothing not going well in this language.
This is not a complete answer as I don't want to do your homework for you.
First of all formatting and indenting your code is going to help you in any programming language. You almost certainly have access to an editor which will do this. Below I've done this.
So, OK, what does a form like (λ (...) ...) denote? Well, its a function which takes some arguments (the first ellipsis) and returns the value of the last form in its body (the second ellipsis), or the only form in its body in a purely functional language.
So, what does:
(λ (a b)
(λ (x y)
...))
Denote? It's a function of two arguments, and it returns something: what is the thing it returns? Well, it's a form which looks like (λ (...) ...): you know what those forms mean already.
And finally we can fill out the last ellipsis (after correcting an error: (-x ...) is not the same as (- x ...)):
(λ (a b)
(λ (x y)
(if b
(+ x y a)
(- x y a))))
So now, how would you call this, and how would you make it do something interesting (like actually adding or subtracting some things)?
(lambda (a b) (lambda (x y) (if b (+ x y a) (- x y a))))
is a function that takes two arguments (that's what (lambda (a b) ...) says).
You can use the substitution method to discover what it produces.
Apply it to 5 and #f:
((lambda (a b) (lambda (x y) (if b (+ x y a) (- x y a)))) 5 #f)
[Replace a with 5 and b with #f in the body]:
(lambda (x y) (if #f (+ x y 5) (- x y 5)))
And this is a function that takes two numbers and produces a new number.
(Note that the #f and the 5 became fixed by the application of the outer lambda.)
It's easier to use the function if we name it (interactions from DrRacket):
> (define question (lambda (a b) (lambda (x y) (if b (+ x y a) (- x y a)))))
> (question 5 #f)
#<procedure>
which is as expected, based on the reasoning above.
Let's name this function as well:
> (define answer (question 5 #f))
and use it:
> (answer 3 4)
-6
or we could use it unnamed:
> ((question 5 #f) 3 4)
-6
or you could do it all inline, but that's a horrible unreadable mess:
> (((lambda (a b) (lambda (x y) (if b (+ x y a) (- x y a)))) 5 #f) 3 4)
-6

Scheme, higher order functions, and curried functions

I need to write a Scheme higher-order function that takes a function of two parameters as its parameter and returns a curried version of the function. I understand this much so far in terms of curried functions:
(define curriedFunction (lambda (x)
(if (positive? x)
(lambda (y z) (+ x y z))
(lambda (y z) (- x y z)))))
(display ((curriedFunction -5) 4 7))
(display "\n")
(display ((curriedFunction 5) 4 7))
If x is negative, it subtracts x y and z. If x is positive, it adds x, y, and z.
In terms of higher order functions I understand this:
(display (map (lambda (x y) (* x y)) '(1 2 3) '(3 4 5)))
And thirdly I understand this much in terms of passing functions in as arguments:
(define (function0 func x y)
(func x y))
(define myFunction (lambda (x y)
(* x y)))
(display (function0 myFunction 10 4))
In the code directly above, I understand that the function "myFunction" could have also been written as this:
(define (myFunction x y)
(* x y))
So now you know where I am at in terms of Scheme programming and syntax.
Now back to answering the question of writing a Scheme higher-order function that takes a function of two parameters as its parameter and returns a curried version of the function. How do I connect these concepts together? Thank you in advance, I truly appreciate it.
Here is a possible solution:
(define (curry f)
(lambda (x)
(lambda (y)
(f x y))))
The function curry takes the function f and returns a function with a single argument x. That function, given a value for its argument, returns another function that takes an argument y and returns the result of applying the original function f to x and y. So, for instance, (curry +) returns a curried version of +:
(((curry +) 3) 4) ; produces 7

Wrapper procedure for sort function failing because of argument

I'm working through SICP, and for one of the exercises I need to create a list of 2 of the 3 larger Numbers in the list. I'm trying to use sort function, but when I use it inside of a function, I'm getting an error:
The object z, passed as the first argument to integer-less?, is not the correct type.
Function is:
(define (myList x y z)
(drop (sort '(x y z) <) 1))
It works fine if I run the second line in the interpreter (substituting variables for actual values), but when I try to use the function it blows up. I'm new to scheme/lisps, so I'm not that familiar with how lists work, but I'm guessing it has something to do with that. I know lisp uses linked lists, so I'm wondering if it has something to do with it reaching the last element and not knowing what to do after that.
Any help would be appreciated!
Edit:
I just tried running:
(define x 4)
(define y 10)
(define z 2)
(drop (sort '(x y z) <) 1)
and got the same error.
'(x y z) is a list containing three symbols, x, y, and z. It's the same as (list 'x 'y 'z).
What you need to use, instead, is (list x y z).
The reason using '(4 10 2) (for example) works is that numbers are "self-evaluating". That means (list '4 '10 '2) is the same as (list 4 10 2).
In addition to #Chris' explanation, here's an easier way which will work for any number of parameters:
(define (myList . lst)
(drop (sort lst <) 1))
Testing:
> (myList 10 1 5)
'(5 10)
> (myList 10 1 5 8)
'(5 8 10)
> (myList 10 1 5 8 -1)
'(1 5 8 10)

Computing a list containing the numbers from x to y

How can I create a method which takes two numbers and prepare a list from first number to second number. The first number is always positive and less than second number? I tried the following but the I am not sure how to have a global variable in Scheme to hold previous values.
(define preplist
(let ((temp '()))
(lambda (x y)
(cond ((= x y) (append temp (list x)))
(else (append temp (list x))
(display x)
(preplist (+ x 1) y))))))
Expected result is: (preplist 3 7) => (3 4 5 6 7)
Can some one please help to resolve this problem?
The solution for (x, y) can be computed as: put x on the front of (x+1, y). It is thus clearly recursive. Like this:
(define (preplist x y)
(if (= x y)
(list y)
(cons x (preplist (+ x 1) y))))
See, it works:
> (preplist 1 4)
(1 2 3 4)
> (preplist 5 7)
(5 6 7)
There are several mistakes in your code, for starters you don't need a global variable defined in a let for storing the result, it's enough to build the answer as you advance in the recursion. And don't use append in this case, if the solution template is followed closely, a cons will suffice for building the output list.
You should stick to the recipe for building a new list recursively; this is how the problem should be solved using that recipe, it's perhaps a bit more idiomatic like this:
(define preplist
(lambda (x y)
(cond ((> x y) ; if the exit condition is met
empty) ; then return the empty list
(else ; otherwise
(cons x ; cons the current element
(preplist (add1 x) y)))))) ; and advance the recursion
An altogether different approach would be to write a tail-recursive solution. This is more efficient because a constant amount of stack is used. It doesn't follow the design recipe as outlined above, but is somewhat more similar to the solution you had in mind - but bear in mind that this doesn't use global variables (only a named let for the iteration) and the solution is accumulated and passed around as a parameter:
(define (preplist x y)
(let loop ((i y) ; named let for iteration
(acc empty)) ; define and initialize parameters
(if (> x i) ; if exit condition is met
acc ; return accumulated value
(loop (sub1 i) ; otherwise advance recursion
(cons i acc))))) ; and add to the accumulator
Of course, as pointed by #dyoo in the comments, in a practical setting you'd use the built-in range procedure which does basically the same as the preplist procedure.

scheme-procedure that takes list as argument

I have to write a Scheme procedure named 'proc3' which takes 2 numbers as arguments
(x,y) and returns a procedure which takes a list as an argument and returns a new
list which is the same as the input list but with x added as the first element
and y added as the second element.
I have so far
(define proc3
(lambda ( x y)
(lambda (list a b c)
(list x y c)
)
)
)
The interpreter compiles it fine, but when I give arguments
i.e proc3( 1 2), it says: cannot reference an identifier before definition.
What does that mean?
The code in the question won't work. Use this as a template for your solution, noticing that a list is just another parameter (I called it lst) e.g., you don't have to write list and enumerate its elements as you did:
(define proc3
(lambda (x y)
(lambda (lst)
<add x y at head of lst>)))
I'll let you figure out the details of how to add x and y at the beginning of lst. For testing it, try something like this:
((proc3 1 2) '(3 4 5))
=> '(1 2 3 4 5)

Resources