Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I am trying to interpret what this scheme function does:
(define (y s lis)
(cond
((null? lis) '() )
((equal? s (car lis)) lis)
(else (y s (cdr lis)))))
It runs but I am not exactly sure what it is doing or trying to do.
Does it need a list to sort or something? I am using DrRacket to run it. I have never seen scheme before
and any help would be greatly appreciated.
It's a search function, that given a value and a list looks for the value in the list. If it finds it, returns the part of the list starting at the point where the element was found. If the value isn't in the list, it returns an empty list. Let's see how this works, step by step:
; define a function called `y` that receives
; as parameters a value `s` and a list `lis`
(define (y s lis)
; we're going to test three possible conditions
(cond
; if the list is empty
((null? lis)
; then we didn't find the value, return the empty list
'())
; if the first element in the list equals the `s` value
((equal? s (car lis))
; then return the list up to this point
lis)
; otherwise
(else
; keep looking in the rest of the list, by recurring over it
(y s (cdr lis)))))
To see the function in action, let's test it with some values:
; call the function with a value that is present in the list
(y 3 '(1 2 3 4 5))
; see how the list is returned starting at the point where the value was found
=> '(3 4 5)
; call the function with a value that is not present in the list
(y 7 '(1 2 3 4 5))
; an empty list is returned
=> '()
To really, really understand how this works, you have to realize that in the last line of the function we're calling the function itself - it's the magic of recursion! Also, it'll help you to understand what each one of the primitive operations used is doing, click on each link to read the documentation, I'm simplifying and summarizing the key points:
define: give a name to a value (in particular, it can be a function)
cond: test for different conditions, execute some expressions depending on which condition was true
null?: test to see if a list is empty
equal?: compare two objects for equality
car: get the first element in a list
cdr: get the rest of the elements in a list
We can go on a mystic journey and treat this definition as it is, a definition. Cryptic? This means equational reasoning, i.e. reasoning through equations, i.e. definitions. Here's what I mean. You have
(define (y s lis)
(cond
((null? lis) '() )
((equal? s (car lis)) lis)
(else (y s (cdr lis)))))
We can re-write this as two equations,
y s lis = lis , if (null? lis) || (equal? s (car lis))
= y s (cdr lis) , otherwise
Here y s lis stands for "the result of Scheme call (y s lis)" and so on.
Clearly we have two cases. One is base case, another describes a reduction step. Re-writing again,
y s lis = y s (cdr lis) , if (not (null? lis)) && (not (equal? s (car lis)))
= lis , otherwise
This is practically in English now. So while lis is not null, and its car isn't s, we proceed along to its cdr, and so on and so forth until either we hit the list's end, or its car is s, and then we stop. So when we've found s, we return the list, otherwise the list is exhausted and the empty list is returned. This is otherwise known as member in Common Lisp. R5RS Scheme's member, as well as Racket's, returns #f when no x is found in the list.
Where is the equational reasoning here, you ask? In treating the RHS as the answer, and re-applying the same set of rules for each reduction step. For example:
y x [a,b,x,c,d,e] ; A
= y x [b,x,c,d,e] ; by 1st rule ; B
= y x [x,c,d,e] ; by 1st rule ; C
= [x,c,d,e] ; by 2nd rule ; D
When we get to apply the 2nd rule, we arrive at the end of the reduction chain, i.e. we get our answer. The result of the Scheme call corresponding to A will be the same as the Scheme call's corresponding to B, or C, or finally D:
(y x (cons a (cons b (cons x z)))) ==
(y x (cons b (cons x z))) ==
(y x (cons x z)) ==
(cons x z)
What's so mystic about it, you ask? Here probably not much; but usually what that means is that by assuming the meaning of a function, and by interpreting the RHS through it, we arrive at the meaning of the LHS; and if this is the same meaning, that is our proof for it. Induction is kind of magical. For more involved examples see How to recursively reverse a list using only basic operations?.
Incidentally structural recursion is also known as folding, so your function is really
y s lis = para (λ (xs x r) (if (equal? x s) xs (r))) '() lis
using one type of folding, paramorphism, with explicit laziness,
para f z lis = g lis
where
g xs = z , if (null? xs)
= f xs (car xs) (λ () (g (cdr xs))) , otherwise
Looks like homework.
Since you are using DrRacket you should add
(y 'e '(q w e r t y))
And hit Debug Q >| and step through it. A different way to write the same code is:
(define (y s lis)
(if (null? lis)
'()
(if (equal? s (car lis))
lis
(y s (cdr lis)))))
Or you can choose Intermediate student with lambda from the language menu in the bottom left and then press Step >|.
That language doesn't support all of Scheme but a small subset, including everything in this procedure. It's great to see how things are evaluated.
I think its a test to see if element s is found inside the list lst. I'm still learning Scheme (but I did get through The Little Schemer so let me try (this has likely been typed and submitted before I I finish this but I'll try anyways).
So define is creating a function called y that takes the arguments s and lst. The first line of this function is cond which goes though each list and tries to find some expression that evaluates to true. The first condition is the exit condition (always have an exit when you iterate) it checks to see if lis is null, if so it returns a quoted empty list (like the null of lists)
The next condition looks to see if the first element of lst (car takes the first element of a list) equals s if so then it returns the rest f the list (this means it found the element).
The last condition is else which is alway true and it calls the function y with the same s and the list minus the first element (cdr returns a sublist of the list minus the first element). Hope this helps (and I hope I was right)
Here is an example of calling this function:
(y 'b (list 'a 'b 'c))
And this returns
('b 'c)
Related
So I'm working my way through SICP, and one of the problems (1.8) is to implement a cube-root procedure analogous to the square-root procedure using the Newton-Raphson method. I wrote the program and tried executing it, but got this error: *: number required, but got #<Closure> [cubert, cubeiter, cubeiter, good-enough, cube, sq, *]
This is my code:
(define (sq x)
(* x x))
(define (cube x)
(*(sq x) x))
(define (abs x)
(if (< x 0)
(-x)
x))
(define (good-enough guess x)
(< (abs (- x (cube guess)) )0.0001))
(define (improve guess x)
(- guess (/ (- (cube guess) 3) (* 3 (sq x)))))
(define (cubeiter guess x)
(if (good-enough guess x)
guess
(cubeiter improve x)))
(define (cubert x) (cubeiter 1.0 x))
(cubert 27)
Could anyone possible explain what this error means and how I can fix it? what is #<Closure>?
Thanks in advance!
#<Closure> is the implementations method of representing a procedure object. If x evaluates to that then (x ...) calls that procedure. Eg. (+ 2 3) ; ==> 5, but + ; ==> #<Closure>. (+ is a primitive so it might display differently, but it really doesn't matter. You are not supposed to print it :) )
I see you call (cubeiter improve x), but it doesn't seem correct that guess is supposed to be a procedure since the initial call passes 1.0 which is a number. Clearly one of them are wrong. Perhaps you was supposed to call improve and have the result be what is passed to cubeiter? eg. (cubeiter (improve ...) x)
Also you have an error in abs. (-x) is not the same as (- x) which is an abbrevation for (- 0 x). You are calling a procedure called -x with no arguments.
The abs error makes my think you are perhaps not testing the parts of your code. If you are not you are going to have problems once the code based gets larger. When making cubeiter it would be nice to know that the procedures you use in it works and that errors then would most likely be in cubeiter and not improve, good-enough, or abs. The whole point of making then individual procedures is to be able to test the parts such that you are sure it works and that you can stop thinking about it's implementation when using it on a higher level of abstraction.
I have the following Common Lisp Function:
(defun test(A &rest indexes)
(if (null (first indexes))
A
(test (nth (+ 1 (first indexes)) A) (rest indexes))
)
)
As far as I know &rest parameters are treated as a list in the function body but since
(rest indexes) also returns a list I'm stuck with nested Lists as parameters.
For example (test '("a" "b" "c" ("d" "e")) 3 1 6 7)
would cause indexes to be ((1 6 7)) at the second call.
Is there any way to pass my list without having this problem?
Basic style rule: don't use &rest arguments for list processing functions.
Why? Common Lisp implementations are allowed to only support up to the value of CALL-ARGUMENTS-LIMIT number of arguments. This number is 50 or larger, depending on implementation.
This means your function might in some implementation process lists not larger as fifty items.
Better: pass the list as a separate argument.
(defun test (A indexes)
...)
(test '("a" "b" "c" ("d" "e")) '(3 1 6 7))
Wrong solution: don't use apply, since it does not solve the problem of limited argument lists.
CLISP
[1]> call-arguments-limit
4096
[2]> (defun l1 (&rest l) l)
L1
[3]> (apply #'l1 (loop repeat 5000 collect 1))
*** - APPLY: too many arguments given to
#<FUNCTION L1 (&REST L)
(DECLARE (SYSTEM::IN-DEFUN L1))
(BLOCK L1 L)>
The following restarts are available:
ABORT :R1 Abort main loop
rest is a accessor function that is paired together with first to give you the first element and the rest of the list. rest is the same as cdr.
&rest is a lambda list keyword that slurps the remaining arguments in the variable name that follows it.
You are really looking for apply. Imagine I make a function that can take 0 or more numeric parameters and add them together:
(defun add (&rest numbers)
(apply #'+ numbers))
Apply can take more than two arguments. The first is the function to call and all but the last are extra arguments that are put in front of the last arguments element. You are guaranteed the implementation supports 50 arguments or upto the number of arguments a function can take in that particular implementation supports above 50.
(apply #'+ 1 2 '(3 4 5)) ; ==> 15
Now recursing by &rest and apply makes inefficient code so you should use higher order functions, loop macro, or make a helper:
;; higher order function
(defun fetch-indexes (a &rest indexes)
(mapcar (lambda (i) (nth i a)) indexes))
;; loop macro
(defun fetch-indexes (a &rest indexes)
(loop :for i :in indexes
:collect (nth i a)))
;; helper function
(defun fetch-indexes (a &rest indexes)
(labels ((helper (indexes)
(if (endp indexes)
'()
(cons (nth (first indexes) a)
(helper (rest indexes))))))
(helper indexes)))
;; test (works the same with all)
(fetch-indexes '(a b c d) 2 3 0 1)
; ==> (c d a b)
Using apply in recursion should be avoided, but I'll show how it's done.
(defun fetch-indexes (a &rest indexes)
(if (endp indexes)
'()
(cons (nth (first indexes) a)
(apply #'fetch-indexes a (rest indexes)))))
In your example you have nested lists. In order for that to work you would need to flatten it as well. I haven't done that so these supports one proper list of elements.
Another solution, albeit a bit more verbose, but less reliant on details of apply is to use a sub-function for the recursion, which just takes a list. The outer "main" entry point takes the &rest indices syntax, while the inner function takes it as a list:
(defun test (a &rest indices)
(labels ((internal-test (indices)
;; ... the recursion thing calling internal-test
))
(internal-test indices)))
In contrast to the (defun add (&rest args) ... ) example, you might still have some arguments before the rest, which in case of using apply would require you to append those to the variable arguments list.
Of course, as Rainer Joswig pointed out, you need to take care only to use this, when the number of variable args is small.
I'm writing a function that takes a list and returns the sum of the squares of all items in the list. Called on (1 2 3) it should return 14: (12 + 22 + 32).
I have this sqsum function:
(define (sqsum lis)
(if (null? lis)
0
(+ (* (car lis) (car lis)) (sqsum (cdr lis)))
)
)
Is this tail recursive? I think it is recursive but not tail recursive.
This is part of my homework and I'm not looking for solution: I just want to know if this is tail recursive or not. If not then I need to read more and find new solutions.
To be tail recursive the recursion has to happen at the very last function, i.e. you cannot do anything with the results from the recursiv call. Here you pass it to +, which makes it non-tail-recursive. The compiler could optimize this away though, and it's pretty easy to do yourself too.
No, it is not tail recursive.
The general approach to making a non-tail recursive function tail-recursive is to include an accumulator, which is an extra argument that carries the current evaluation of the procedure through your recursive calls.
Incidentally, this is also where "helper" functions are very useful. The general practice is to define your function so that it does not take the accumulator, define a helper function within it that does take the accumulator, and then have the main function do little besides call the helper function. You'll see what I mean in a sec.
In your case (if I'm remembering my Scheme properly :p):
(define (sqsum lis)
(define (sqsum-h lis acc)
(if (null? lis)
acc
(sqsum-h (cdr lis) (+ acc (* (car lis) (car lis))))
)
)
(sqsum-h lis 0)
)
This is tail-recursive because the last thing any recursive call does is immediately return the result of another function without modifying it.
I'm trying to pass a list to a function in Lisp, and change the contents of that list within the function without affecting the original list. I've read that Lisp is pass-by-value, and it's true, but there is something else going on that I don't quite understand. For example, this code works as expected:
(defun test ()
(setf original '(a b c))
(modify original)
(print original))
(defun modify (n)
(setf n '(x y z))
n)
If you call (test), it prints (a b c) even though (modify) returns (x y z).
However, it doesn't work that way if you try to change just part of the list. I assume this has something to do with lists that have the same content being the same in memory everywhere or something like that? Here is an example:
(defun test ()
(setf original '(a b c))
(modify original)
(print original))
(defun modify (n)
(setf (first n) 'x)
n)
Then (test) prints (x b c). So how do I change some elements of a list parameter in a function, as if that list was local to that function?
Lisp lists are based on cons cells. Variables are like pointers to cons cells (or other Lisp objects). Changing a variable will not change other variables. Changing cons cells will be visible in all places where there are references to those cons cells.
A good book is Touretzky, Common Lisp: A Gentle Introduction to Symbolic Computation.
There is also software that draws trees of lists and cons cells.
If you pass a list to a function like this:
(modify (list 1 2 3))
Then you have three different ways to use the list:
destructive modification of cons cells
(defun modify (list)
(setf (first list) 'foo)) ; This sets the CAR of the first cons cell to 'foo .
structure sharing
(defun modify (list)
(cons 'bar (rest list)))
Above returns a list that shares structure with the passed in list: the rest elements are the same in both lists.
copying
(defun modify (list)
(cons 'baz (copy-list (rest list))))
Above function BAZ is similar to BAR, but no list cells are shared, since the list is copied.
Needless to say that destructive modification often should be avoided, unless there is a real reason to do it (like saving memory when it is worth it).
Notes:
never destructively modify literal constant lists
Dont' do: (let ((l '(a b c))) (setf (first l) 'bar))
Reason: the list may be write protected, or may be shared with other lists (arranged by the compiler), etc.
Also:
Introduce variables
like this
(let ((original (list 'a 'b 'c)))
(setf (first original) 'bar))
or like this
(defun foo (original-list)
(setf (first original-list) 'bar))
never SETF an undefined variable.
SETF modifies a place. n can be a place. The first element of the list n points to can also be a place.
In both cases, the list held by original is passed to modify as its parameter n. This means that both original in the function test and n in the function modify now hold the same list, which means that both original and n now point to its first element.
After SETF modifies n in the first case, it no longer points to that list but to a new list. The list pointed to by original is unaffected. The new list is then returned by modify, but since this value is not assigned to anything, it fades out of existence and will soon be garbage collected.
In the second case, SETF modifies not n, but the first element of the list n points to. This is the same list original points to, so, afterwards, you can see the modified list also through this variable.
In order to copy a list, use COPY-LIST.
it's nearly the same as this example in C:
void modify1(char *p) {
p = "hi";
}
void modify2(char *p) {
p[0] = 'h';
}
in both cases a pointer is passed, if you change the pointer, you're changing the parameter copy of the pointer value (that it's on the stack), if you change the contents, you're changing the value of whatever object was pointed.
You probably have problems because even though Lisp is pass-by-value references to objects are passed, like in Java or Python. Your cons cells contain references which you modify, so you modify both original and local one.
IMO, you should try to write functions in a more functional style to avoid such problems. Even though Common Lisp is multi-paradigm a functional style is a more appropriate way.
(defun modify (n)
(cons 'x (cdr n))
If f is a numerical function and n is a positive integer, then we can form the nth repeated application of f, which is defined to be the function whose value at x is f(f(...(f(x))...)). For example, if f is the function x + 1, then the nth repeated application of f is the function x + n. If f is the operation of squaring a number, then the nth repeated application of f is the function that raises its argument to the 2^nth power. Write a procedure that takes as inputs a procedure that computes f and a positive integer n and returns the procedure that computes the nth repeated application of f. Your procedure should be able to be used as follows:
((repeated square 2) 5)
625
You can use this to simplify the answer:
(define (compose f g) (lambda (x) (f (g x))))
(define (repeated f n)
(if (= n 1)
f
(compose f (repeated f (- n 1)))))
Did you just delete and reask this question? I'm copying my former answer here (thankfully, my browser had cached it):
Well, you probably want something like this, right?
((repeated square 3) 5)
-> (square ((repeated square 2) 5))
-> (square (square ((repeated square 1) 5)))
-> (square (square (square ((repeated square 0) 5))))
-> (square (square (square (identity 5))))
(I don't know whether identity is predefined in Scheme. If not, it's easy to write.)
Now, this is not directly reproducible because you can't magically enclose code outside of the call to repeated with arbitrary stuff. However, what do these reduction steps look like when rewritten using compose? Can you make out a pattern in the resulting list of steps and reproduce it?