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)
Related
Very new to Scheme, so I'm sorry for a basic question. Whenever I print out something as a test, my result always contains the word "list" in the list that is printed.
My code:
(define get-lower-half
(lambda (lst n)
(if (< n (quotient (length lst) 2))
(cons (list-ref lst n) (get-lower-half lst (+ n 1)))
'())))
(get-lower-half '(1 2 3 4 5) 0)
My result is then:
(list 1 2)
instead of just
(1 2)
The examples of using cons I find online don't have this problem, what the heck am I doing wrong here? I'm using DrRacket as my IDE with Intermediate Student with Lambda as the language.
I'm pretty sure you're expecting '(1 2) (a list), and not (1 2).
(1 2) is not a valid procedure in Racket or in the intermediate language.
In the intermediate language, lists are represented with the list procedure, (list 1 2) and not '(1 2) like in regular Racket. What you are seeing is regular intermediate language behaviour.
In Scheme there are the concepts of datum and datum syntax.
A datum is the mathematical part of an object. For example, the number 3 or the pair (x y) is a datum. A datum syntax is a way to represent datum. For example, #x03 or 3 or #b11 are datum syntax for representing the datum 3. In the same way, the datum (x y) can be represented in syntax as (x y) or (x . (y . ())).
The scheme output has many options to print the datum. Some output functions print the datum such that what they print to be valid code that creates the given datum or they can print the datum as valid syntax as data that will create that datum.
See io-ports and datum definitions.
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)
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.
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).
I'm trying to implement a function in scheme that splits the given list with the function that is also given as parameter to function. To exemplify:
(splitby '("a" "b" "cc" "ab" "abc" "a" "b")
(lambda (x y) (= (string-length x) (string-length y))))
should return (("a" "b") ("cc "ab") ("abc") ("a" "b"))
I'm pretty beginner in Scheme so it is really hard to understand how this 'function like' parameter works, and while implementing such a function what should I do?
In Scheme, functions are objects like numbers, strings, etc. So in this case, your example is equivalent to this:
(define (equal-length x y)
(= (string-length x) (string-length y)))
(splitby '("a" "b" "cc" "ab" "abc" "a" "b") equal-length)
The use of the function is to allow the splitting criterion to be customised. In this case, items are in the same group for as long as the given function returns a true value; otherwise a new group is created.
To get started, write a group-equal function, that groups equal elements together:
(define (group-equal lst)
...)
where, for example,
(group-equal '(1 2 2 3 3 3 4))
returns
((1) (2 2) (3 3 3) (4))
If you successfully implement that, then it's identical to your splitby function, except that you use the given function (equal-length, for example) instead of equal? (as group-equal might use).
Firstly, in Scheme, everything is inside parentheses. So If you want to apply the function f to values x and y, you write:
(f x y)
So you simply need to put splitby inside the first set of parens.
Secondly, functions can be passed as values into other functions, just like data is passed.
So if I have a functions:
(define (double x)
(* x 2))
I can write another function which takes double as an argument:
(define (change_result f x)
(f (+ 3 x)))
; (change_result double 6) returns 18
I can also do this the same way, if I use a lambda (anonymous) function:
(change_result (lambda (x) (* 3 x)) 10)