Could someone tell me what potential problems we would get from changing these two first functions dedicated to removing duplicates from a list to the last two that are for streams
(define (memq item x)
(cond ((null? x ) #f)
((eq? item (car x )) x)
(else (mem item (cdr x)))))
(define (r lst)
(cond ((null? lst) '())
((not (memq (car lst ) (scdr lst)))
(cons(car lst) (r (cdr lst))))
(else (r ( cdr last)))))
Under we have the stream version, all I have done here as you can see is changing car,cons and cdr to stream versions. I read that this will have potential problems but I cannot see why.
(define (memq item x)
(cond ((null? x ) #f)
((eq? item (stream-car x )) x)
(else (memq item (stream-cdr x)))))
(define (r lst)
(cond ((null? lst) '())
((not (memq (stream-car lst ) (stream-cdr lst)))
(cons-stream (stream-car lst) (r (stream-cdr lst))))
(else (r ( stream-cdr lst)))))
A big part of the point of streams is that they may potentially be infinite, because they are generated as needed. When the stream version of your r function is called on any infinite stream, it will never produce a single value. Can you see why this is?
Related
last-non-zero takes a list of numbers and return the last cdr whose car is 0.
So, I can implement it using continuations, but how do I do this with natural recursion.
(define last-non-zero
(lambda (ls)
(let/cc return
(letrec
((lnz
(lambda (ls)
(cond
((null? ls) '())
((zero? (car ls)) ;; jump out when we get to last 0.
(return (lnz (cdr ls))))
(else
(cons (car ls) (lnz (cdr ls))))))))
(lnz ls)))))
Here's an obvious version which is not tail-recursive:
(define (last-non-zero l)
;; Return the last cdr of l which does not contain zero
;; or #f if there is none
(cond
((null? l)
#f)
((zero? (car l))
(let ((lnzc (last-non-zero (cdr l))))
;; This is (or lnzc (cdr l)) but that makes me feel bad
(if lnzc
lnzc
(cdr l))))
(else
(last-non-zero (cdr l)))))
Here is that version turned into a tail-recursive equivalent with also the zero test moved around a bit.
(define (last-non-zero l)
(let lnzl ([lt l]
[r #f])
(if (null? lt)
r
(lnzl (cdr lt) (if (zero? (car lt)) (cdr lt) r)))))
It's much clearer in this last version that the list is traversed exactly once.
Please indicate if I have correctly understood the problem:
#lang scheme
; returns cdr after last zero in lst
(define (last-non-zero lst)
; a helper function with 'saved' holding progress
(define (lnz-iter lst saved)
(if (null? lst)
saved
(if (zero? (car lst))
(lnz-iter (cdr lst) (cdr lst))
(lnz-iter (cdr lst) saved))))
(lnz-iter lst '()))
(last-non-zero '(1 2 3 0 7 9)) ; result (7 9)
Racket's takef-right can do it:
> (takef-right '(1 2 0 3 4 0 5 6 7) (lambda (n) (not (zero? n))))
'(5 6 7)
But assuming you have an assignment where you're supposed to write the logic yourself instead of just using a built in function, one easy if not very efficient approach is to reverse the list, build a new list out of everything up to the first zero, and return that. Something like:
(define (last-non-zero ls)
(let loop ([res '()]
[ls (reverse ls)])
(if (or (null? ls) (zero? (car ls)))
res
(loop (cons (car ls) res) (cdr ls)))))
Using your implementation where you return the argument in the event there are no zero you can just have a variable to keep the value you think has no zero values until you hit it and then update both:
(define (last-non-zero lst)
(let loop ((lst lst) (result lst))
(cond ((null? lst) result)
((zero? (car lst)) (loop (cdr lst) (cdr lst)))
(else (loop (cdr lst) result)))))
(last-non-zero '()) ; ==> ()
(last-non-zero '(2 3)) ; ==> (2 3)
(last-non-zero '(2 3 0)) ; ==> ()
(last-non-zero '(2 3 0 1 2)) ; ==> (1 2)
(define last-non-zero
(lambda (l)
((lambda (s) (s s l (lambda (x) x)))
(lambda (s l* ret)
(if (null? l*)
(ret '())
(let ((a (car l*))
(r (cdr l*)))
(if (zero? a)
(s s r (lambda (x) x))
(s s r
(lambda (r)
(ret (cons a r)))))))))))
Also possible, to use foldr:
(define (last-non-zero l)
(reverse (foldl (lambda (e res) (if (zero? e) '() (cons e res))) 0 l)))
Or use recursion:
(define (last-non-zero l (res '()))
(cond ((empty? l) res)
((zero? (car l)) (last-non-zero (cdr l) (cdr l)))
(else (last-non-zero (cdr l) res))))
Getting an error for my binary search tree that I created in scheme.
$gosh main.sc
*** ERROR: list required, but got 5
Stack Trace:
_______________________________________
This is my code. I think the error has to do with how I am calling the functions, but I am not sure what exactly is wrong. I am calling the insert function with the two required parameters: tree, and a value of 5.
(define (member? t v)
(cond
((null? t)
#f
)
((< node (car t))
(member? (cadr t) v))
((> node (car t))
(member? (caddr t) v))
(else
#t
)
)
)
(define (insert t v)
(cond
((null? t)
(list v '() '())
)
((< v (car t))
(list (car t) (insert (cadr t) v) (caddr t))
)
((>= v (car t))
(list (car t) (cadr t) (insert (caddr t) v))
)
(else
t
)
)
)
(define (fold func val lst)
(if (null? lst) val (fold func (func val (car lst)) (cdr lst))))
(define (build lst)
(fold (lambda (t v) (insert t v)) '() lst))
(define t (list 10 '() '()))
(insert t 5)
display (member t 5)
display t
You care calling (member t 5) which is the same as (member '(10 '() '()) 5). Now member is not the same as your defined member? since it has a different name. member is the core library that looks like this:
(define (member obj lst)
(cond ((null? lst) #f)
((equal? obj (car lst)) lst)
(else (member obj (cdr lst)))))
Your member? has the two parameters swapped so when you miswrote the name and used the report version member 5 is not null, then it will do (car 5) and that will fail miserably. The error message that 5 is not of the required type list is pretty decent. It might spell the beans that it was member that failed though.
Another thing. If you replace the call to member with a call to member? you hit more problems. You use a variable node that is not defined anywhere.
The indentation and placing of parentheses is not goo lisp style. Your code should be written like this:
;; node doesn't exist in OPs code, but my implementation doesn't like member? without it
(define node 5)
;; possible typo by using the variable node ?
(define (member? t v)
(cond
((null? t)
#f)
((< node (car t))
(member? (cadr t) v))
((> node (car t))
(member? (caddr t) v))
(else
#t)))
(define (insert t v)
(cond
((null? t)
(list v '() '()))
((< v (car t))
(list (car t) (insert (cadr t) v) (caddr t)))
((>= v (car t))
(list (car t) (cadr t) (insert (caddr t) v)))
(else
t)))
(define (fold func val lst)
(if (null? lst) val (fold func (func val (car lst)) (cdr lst))))
(define (build lst)
(fold (lambda (t v) (insert t v)) '() lst))
(define t (list 10 '() '()))
(insert t 5)
;; NB doesn't call a procedure, just evaluates it.
display
;; Here the arguments are the wrong order and you don't use memeber?
(member t 5)
;; NB doesn't call a procedure, just evaluates it.
display
t
Can someone show me the error in this code please?
I want to generalize the member function to support nested lists. I need to search thing inside the nested list and return the rest of the list when I found thing. I don't really understand whats wrong with the code below.
(define (memberk thing lis)
(cond
((null? lis) #f)
((list? (car lis))
(cons (memberk thing (car lis))
(memberk thing (cdr lis))))
(else
(if (equal? (car lis) thing)
lis
(memberk thing (cdr lis))))))
Expexted output: (memberk 3 '(1 4 (3 1) 2)) = '((3 1) 2)
Actual output from the code above: '((3 1) . #f)
So how I see this you would like the top level cons that has the key found somewhere in car. I'm thinking something like:
(define (memberk needle lst)
(define (found? haystack)
(or (equal? needle haystack)
(and (pair? haystack)
(or (found? (car haystack))
(found? (cdr haystack))))))
(let loop ((lst lst))
(cond ((null? lst) #f)
((found? (car lst)) lst)
(else (loop (cdr lst))))))
(memberk '(a) '(a b (b (a) c) c d)) ; ==> ((b (a) c) c d)
Something like this?
It is a bit unclear what you want - since there is only one test case.
(define (memberk thing lis)
(cond
[(null? lis)
#f]
[(and (cons? (car lis)) (memberk thing (car lis)))
=> (λ (found) (cons found (cdr lis)))]
[(equal? (car lis) thing)
lis]
[else
(memberk thing (cdr lis))]))
I've been working on a vector multiply function in scheme and have found myself in rut. I dont want to use any looping and I dont want to use any scheme built in functions other than the ones I've already included. I've created a helper function called rotate and dotproduct. I can get the correct values if I do this in racket (vectormult '(1 2 -1) (rotate '((0 2 3) (1 2 0) (1 0 3)))). How can I rotate the initial parameter without re-rotating after every recursive call? NOTE: I dont want to introduce additional paramaters. If my logic/approach to this is all wrong please help me get on the right track.
Code
(define dotproduct
(lambda (l1 l2)
(if (or (null? l1) (null? l2))
0
(+ (* (car l1) (car l2)) (dotproduct (cdr l1) (cdr l2))))))
(define getFirsts
(lambda (l)
(cond
((null? l) `())
(else (cons (first* l) (getFirsts (cdr l)))))))
(define removeFirsts
(lambda (l)
(cond
((null? l) `())
((null? (car l)) `())
(else (cons (cdr (car l)) (removeFirsts (cdr l)))))))
(define rotate
(lambda (l)
(cond
((null? l) `())
((null? (first* l)) `())
(else (cons (getFirsts l) (rotate (removeFirsts l)))))))
(define vectormult
(lambda (l1 l2)
(cond
((null? l2) `())
(else (cons (dotproduct l1 (car l2)) (vectormult l1 (cdr l2)))))))
If I understand the question, you could rename your current vectormult to, say, rotatedvectormult (and change its recursive call accordingly), and then have vectormult just rotate the parameter before calling rotatedvectormult. This way, rotatedvectormult would know the parameter was already rotated, but vectormult could still take an unrotated vector.
I ended up ditching the rotate function in favor of adding 2 functions getFirsts and removeFirsts.
Code
(define getFirsts
(lambda (l)
(cond
((null? l) `())
(else (cons (first* l) (getFirsts (cdr l)))))))
(define removeFirsts
(lambda (l)
(cond
((null? l) `())
((null? (car l)) `())
(else (cons (cdr (car l)) (removeFirsts (cdr l)))))))
;(define rotate
; (lambda (l)
; (cond
; ((null? l) `())
; ((null? (first* l)) `())
; (else (cons (getFirsts l) (rotate (removeFirsts l)))))))
(define vectormult
(lambda (l1 l2)
(cond
((null? (first* l2)) `())
(else (cons (dotproduct l1 (getFirsts l2)) (vectormult l1 (removeFirsts l2)))))))
I found this lisp function while I was googling
(defun filter (lst items-to-filter)
(cond ((null lst) nil)
((member (car lst) items-to-filter) #1=(filter (cdr lst) items-to-filter))
(t (cons (car lst) #1#))))
It's just set difference, but this is the first time i see #1= and #1#, syntax. I think I understand what it means just by looking at the code, but I am not too sure. I think the #1= is used to label an expression so as not to retype it later when needed, one can just refer to it by #index#, in this case index=1. I was wondering if someone could shed some light on this. What are these constructs called, if there's a reference for them, and if they are widely used in modern lisp code. Thanks
To see it in written source code is very very unusual. Most of the time you see it in data. It is used to create or print shared data items in s-expressions. This way you can also read or print circular s-expressions.
You could use it for easier creation of repeated code, but usually one writes functions or macros for that. Functions have the advantage that they save code space - unless they are inlined.
CL-USER 3 > (pprint '(defun filter (lst items-to-filter)
(cond ((null lst) nil)
((member (car lst) items-to-filter)
#1=(filter (cdr lst) items-to-filter))
(t (cons (car lst) #1#)))))
(DEFUN FILTER (LST ITEMS-TO-FILTER)
(COND ((NULL LST) NIL)
((MEMBER (CAR LST) ITEMS-TO-FILTER)
(FILTER (CDR LST) ITEMS-TO-FILTER))
(T
(CONS (CAR LST) (FILTER (CDR LST) ITEMS-TO-FILTER)))))
As you see above the printer does not print it that way. Why is that?
There is a global variable *print-circle* which controls it. For above example it was set to NIL. Let's change that:
CL-USER 4 > (setf *print-circle* t)
T
CL-USER 5 > (pprint '(defun filter (lst items-to-filter)
(cond ((null lst) nil)
((member (car lst) items-to-filter)
#1=(filter (cdr lst) items-to-filter))
(t (cons (car lst) #1#)))))
(DEFUN FILTER (LST ITEMS-TO-FILTER)
(COND ((NULL LST) NIL)
((MEMBER (CAR LST) ITEMS-TO-FILTER)
#1=(FILTER (CDR LST) ITEMS-TO-FILTER))
(T
(CONS (CAR LST) #1#))))
So this shows that one can read and print such s-expressions in Common Lisp
Sharing some source code data structures is more common in computed code:
CL-USER 22 > (defmacro add-1-2-3 (n) `(,n 1 2 3))
ADD-1-2-3
CL-USER 23 > (walker:walk-form '(+ (add-1-2-3 4) (add-1-2-3 5)))
(+ (4 . #1=(1 2 3)) (5 . #1#))