Interleave Scheme, cons contract violation - scheme

I am new to writing scheme for a class. We were asked to write an interleave method, and here is what I have so far:
(define (Interleave L1 L2)
(if (null? L1) L2)
(if (null? L2) L1)
(cons (car L1) (Interleave (L2) (cdr L1))))
I am trying to run it in DrRacket using (Interleave '(1 2 3) '(4 5 6))
My expected output should be (1 4 2 5 3 6), but instead I keep getting an error:
car: contract violation
expected: pair?
given: ()
And I have no idea how to fix it. Any help is appreciated!

Since you mention DrRacket I assume you have written it in some other editor and pasted the code in? DrRacket usually indent correctly. You can force it with CTRL+i. Here is your code with that done in DrRacket:
(define (Interleave L1 L2)
(if (null? L1) L2) ; dead code
(if (null? L2) L1) ; dead code
(cons (car L1) (Interleave (L2) (cdr L1)))) ; always done
The last line always happen so your test if either are null? doesn't do anything. they evaluate to L2 and L2 but since it is not the tail expression. In order for you if to have an impact the rest of your code have to be in them. You can also use cond which prevents the need to nest if so that it looks more like elseif does on other languages.
Since your procedure does not have a base case it fails when car or cdr fails when the argument is the empty list.
PS: I notice that you check if L2 is null? but on the last line you do (L2) which means you call it as if L2 is a procedure like cons and car. That will not work.

Related

Remove match elements from list using Scheme

I am trying to write a function which takes in two lists, L1 and L2, and returns a list which contains all of L1 except for the elements which are also found in L2.
Example: Pass in '(1 2 3) '(3 4 5) and the return should be '(1 2)
I have written a helper function called removeOne which is working perfectly fine:
(define (removeOne x L)
(cond ((null? L) '())
((= (car L) x) (removeOne x (cdr L)))
(#t (cons (car L) (removeOne x (cdr L))))))
My issue is with the main function which is supposed to use removeOne to get rid of all matching elements from L1. I have written this so far:
(define (removeAll L1 L2)
(cond ((null? L1) '())
((null? L2) '())
((= (car L1) (car L2)) (removeOne (car L2) L1))
(#t (removeAll (cdr L1) L2))))
This is currently returning () no matter what lists I use as input.
I feel like I'm close to getting this to work. Any help would be greatly appreciated!
I have hard time following your logic in removeAll. Since you have written a removeOne, shouldn't you just call removeOne with all elements of L2?
Besides, this condition
((null? L2) '())
is strange.
You are supposed to return all elements of L1 that are not in L2. And L2 is empty. So, all elements of L1 that are not in '()... how can this be the empty list? No elements are in (). So, "all elements of L1 that are not in ()" is just a convoluted way to say "L1". So, clearly, case (null? L2) should be associated to result L1.
So, if I summarize the recursion of removeAll, what you want to do is remove (car L2) from L1, then remove all of (cdr L2) from that result (or the other way, it doesn't really matter). Unless L2 is empty, in which case, removeAll has nothing to remove.
So
(define (removeAll L1 L2)
(if (null? L2)
L1
(removeAll (removeOne (car L2) L1) (cdr L2))))
Or,
(define (removeAll L1 L2)
(if (null? L2)
L1
(removeOne (car L2) (removeAll L1 (cdr L2)))))
(same result. The 1st one remove first (car L2) from L1, then remove (cdr L2) from the result. The second one remove first (cdr L2) from L1, then remove (car L2) from the result. In other words, the 1st one remove one by one elements of L2 from L1, in the normal order, while the second one does it in reverse order.
There are a few atomic functions for searchcing lists, like member, that you can use. Using such a function you will reduce your problem to a recursive function with 3 cases: null, match and otherwise. Depending on your interest to compare objects, you will use member or other one, they use all a different equality operator.

Getting the ordered leaves of a tree in scheme

I'm going through an exercise to grab the 'leaves' of a nested list in scheme (from SICP). Here is the exercise input-output:
(define x (list (lis 1 2) (list 3 4)))
(fringe x)
; (1 2 3 4)
(fringe (list x x))
; (1 2 3 4 1 2 3 4)
Now, I've come up with two answers for this: one recursive and one iterative. Here are my two implementations below:
(define (fr lst)
(cond ((null? lst) '())
((not (pair? (car lst))) (cons (car lst) (fr (cdr lst))))
(else (append (fr (car lst)) (fr (cdr lst))))))
(define (add-element-to-list lst elem)
(if (null? lst)
(list elem)
(cons (car lst) (add-element-to-list (cdr lst) elem))))
(define (fringe lst)
(define L '())
(define (iter lst)
(if (not (pair? (car lst)))
(set! L (add-element-to-list L (car lst))) ; update the list if it's a leaf
(iter (car lst))) ; otherwise recurse
(if (not (null? (cdr lst))) (iter (cdr lst))) ; and if we have a cdr, recurse on that
L
)
(iter lst)
)
(fringe x)
(fr x)
(fr (list x x))
(fringe (list x x))
; (1 2 3 4)
; (1 2 3 4)
; (1 2 3 4 1 2 3 4)
; (1 2 3 4 1 2 3 4)
; OK
The problem for me is, this exercise took me forever to figure out with a ton of head-bashing along the way (and it's still difficult for me to 'get it' as I write this up). Here are a few things I struggled with and seeing if there are any suggestions on ways to deal with these issues in scheme:
I thought initially that there are two cases. The normal/scalar case and the nested case. However, it seems like there are actually three! There's the normal case, the nested case, and then the null case -- and inner-lists also have the null case! Is there a good general pattern or something to account for the null case? Is this something that comes up a lot?
In the iterative case, why do I have to return L at the end? Why doesn't (iter lst) just return that (i.e., if I removed the standalone-L at the bottom of the iter function).
Finally, is there a 'cleaner' way to implement the iterative case? It seems like I have so much code, where it could probably be improved on.
The reason there are three cases is that you are importing some scalar / vector distinction from some other language: Scheme doesn't have it and it is not helpful. Instead a list is a recursively-defined object: a list is either the empty list, or it is a pair of something and a list. That means there are two distinctions to make, not one: is an object a pair, and is an object the empty list:
(define (lyst? o)
(or (null? o)
(and (pair? o) (lyst? (cdr o)))))
That's completely different than a vector / scalar distinction. I don't know what language you're getting this from, but just think about how the maths of this would work: vectors are defined over some scalar field, and there is no vector which is also a scalar. But for lists there is a list which is not a pair. Just stop thinking about vectors and scalars: it is not a helpful way to think about lists, pairs and the empty list.
The iterative version is too horrible to think about: there's a reason why SICP hasn't introduced set! yet.
First of all it's not actually iterative: like most of the 'iterative' solutions to this problem on the net it looks as if it is, but it's not. The reason it's not is that the skeleton of the iter function looks like
if blah
recurse on the first element of the list
otherwise do something else
if other blah
iterate on the rest of the list
And the critical thing is that both (1) and (2) always happen, so the call into the car of the list is not a tail call: it's a fully-fledged recursive call.
That being said you can make this much better: the absolutely standard way of doing this sort of thing is to use an accumulator:
(define (fringe l)
(define (fringe-loop thing accum)
(cond
((null? thing)
;; we're at the end of the list or an element which is empty list
accum)
((pair? thing)
;; we need to look at both the first of the list and the rest of the list
;; Note that the order is rest then first which means the accumulator
;; comes back in a good order
(fringe-loop (car thing)
(fringe-loop (cdr thing) accum)))
(else
;; not a list at all: collect this "atomic" thing
(cons thing accum))))
(fringe-loop l '()))
Note that this builds the fringe (linear) list from the bottom up, which is the natural way of building linear lists with recursion. To achieve this it slightly deviously orders the way it looks at things so the results come out in the right order. Note also that this is also not iterative: it's recursive, because of the (fringe-loop ... (fringe-loop ...)) call. But this time that's much clearer.
The reason it's not iterative is that the process of searching a (tree-like, Lisp) list is not iterative: it's what SICP would call a 'recursive process' because (Lisp's tree-like) lists are recursively defined in both their first and rest field. Nothing you can do will make the process iterative.
But you can make the code to appear iterative at the implementation level by managing the stack explicitly thus turning it into a tail recursive version. The nature of the computational process doesn't change though:
(define (fringe l)
(define (fringe-loop thing accum stack)
(cond
((null? thing)
;; ignore the () sentinel or () element
(if (null? stack)
;; nothing more to do
accum
;; continue with the thing most recently put aside
(fringe-loop (car stack) accum (cdr stack))))
((pair? thing)
;; carry on to the right, remembering to look to the left later
(fringe-loop (cdr thing) accum (cons (car thing) stack)))
(else
;; we're going to collect this atomic thing but we also need
;; to check the stack
(if (null? stack)
;; we're done
(cons thing accum)
;; collect this and continue with what was put aside
(fringe-loop (car stack) (cons thing accum) (cdr stack))))))
(fringe-loop l '() '()))
Whether that's worth it depends on how expensive you think recursive calls are and whether there is any recursion limit. However the general trick of explicitly managing what you are going to do next is useful in general as it can make it much easier to control search order.
(Note, of course, that you can do a trick like this for any program at all!)
It's about types. Principled development follows types. Then it becomes easy.
Lisp is an untyped language. It's like assembler on steroids. There are no types, no constraints on what you're able to code.
There are no types enforced by the language, but still there are types, conceptually. We code to types, we handle types, we produce values to a given specs i.e. values of some types as needed for the pieces of bigger system to interface properly, for the functions we write to work together properly, etc. etc.
What is it we're building a fringe of? Is it a "list"?
What is a "list"? Is it
(define (list? ls)
(or (null? ls)
(and (pair? ls)
(list? (cdr ls)))))
Is this what we're building a fringe of? How come it says nothing about the car of the thing, are we to ignore anything that's in the car? Why, no, of course not. We're not transforming a list. We're actually transforming a tree:
(define (tree? ls)
(or (null? ls)
(and (pair? ls)
(tree? (car ls))
(tree? (cdr ls)))))
Is it really enough though to only be able to have ()s in it? Probably not.
Is it
(define (tree? ls)
(or (null? ls)
(not (pair? ls)) ;; (atom? ls) is what we mean
(and ;; (pair? ls)
(tree? (car ls))
(tree? (cdr ls)))))
It 1 a tree? Apparently it is, but let's put this aside for now.
What we have here, is a structured, principled way to see a piece of data as belonging to a certain type. Or as some say, data type.
So then we just follow the same skeleton of the data type definition / predicate, to write a function that is to process the values of said type in some specific way (this is the approach promoted by Sterling and Shapiro's "The Art of Prolog").
(define (tree-fringe ls)
So, what is it to produce? A list of atoms in its leaves, that's what.
(cond
((null? ls)
A () is already a list?.
ls)
((not (pair? ls)) ;; (atom? ls) is what we mean
(handle-atom-case ls))
Let's put this off for now. On to the next case,
(else
;; (tree? (car ls))
;; (tree? (cdr ls))
both car and cdr of ls are tree?s. How to handle them, we already know. It's
(let ((a (tree-fringe (car ls)))
(b (tree-fringe (cdr ls)))
and what do we do with the two pieces? We piece them together. First goes the fringe from the left, then from the right. Simple:
(append a b )))))
(define (handle-atom-case ls)
;; bad name, inline its code inside
;; the `tree-fringe` later, when we have it
And so, what type of data does append expect in both its arguments? A list?, again.
And this is what we must produce for an atomic "tree". Such "tree" is its own fringe. Except,
;; tree: 1 2
;; fringe: ( 1 ) ( 2 )
it must be a list?. It's actually quite simple to turn an atomic piece of data, any data, into a list? containing that piece of data.
........ )
And that was the only non-trivial thing we had to come up with here, to get to the solution.
Recursion is about breaking stuff apart into the sub-parts which are similar to the whole thing, transforming those with that same procedure we are trying to write, then combining the results in some simple and straightforward way.
If a tree? contains two smaller trees?, well, we've hit the jackpot -- we already know how to handle them!
And when we have structural data types, we already have the way to pick them apart. It is how they are defined anyway.
Maybe I'll address your second question later.

Need a hint on a homework question which asks to add numbers in a list in a particular way

This is a homework question
The function takes in a list as the parameter, which may contain as many layers as sublists as needed For example, '(a (1 b 3)) or '((a 3 5) (b (3 1) 4)). The output has the same list structure of the input (meaning that sublists are maintained), but the car of each list is the sum of all numbers in the list. And all other non-numeric values are discarded. As an example output, consider '((a 3 5) (b (3 1) 4)), the output should be '(16 (8) (8 (4))). Also, only use basic scheme instructions/operations such as + - * /, car, cdr, cons, append, null?, number?, if/else, cond, etc.. Cannot Use a helper method.
So far this is the code I have, which sometimes partially does the job. But I'm having a really hard time figuring out how to get the sum from the sublists to add up at one spot at the car of the outmost list.
(define partialsums*
(lambda (lis)
(cond
[(null? lis) '(0)]
[(list? (car lis)) (cons (partialsums* (car lis)) (if (not (null? (cdr lis))) (partialsums* (cdr lis)) '()))]
[(number? (car lis)) (cons (+ (car lis) (car (partialsums* (cdr lis)))) '())]
[else (cons (+ 0 (car (partialsums* (cdr lis)))) '())])))
I've already spent several hours on this but couldn't quite grasp how to correctly approach the problem, probably because this is my first week using scheme :(. Any help is appreciated.
Also, I cannot use a helper method. Everything needs to be done inside one function in a recursive style. letrec is not allowed either.
To make life easy, you should model the data. Since there are no types, we can do this informally.
What is the structure of the input?
We can model it like "Data Definitions" from How to Design Programs. Read the "Intertwined Data" section because our data definition is similar to that of an S-expression.
; A NestedElem is one of:
; - Atom
; - NestedList
; An Atom is one of:
; - Number
; - Symbol
; A NestedList is one of
; - '()
; - (cons NestedElem NestedList)
We can define an atom? predicate to help us differentiate between clauses of the kinds of data in our program.
; Any -> Boolean
; is `a` an atom?
(define atom?
(lambda (a)
(or (number? a)
(symbol? a))))
The structure of the program should match the structure of the Data.
So we define a "template" on our data. It distinguished and destructs each data into clauses. It further de-structures the rhs of a clause.
; NestedElem -> ...
(define nested-elem-template
(lambda (ne)
(cond
[(atom? ne) ...]
[else ...])))
; Atom -> ...
(define atom-template
(lambda (atom)
(cond [(number? atom) ...]
[(symbol? atom) ...])))
; NestedList -> ...
(define nested-list-template
(lambda (nl)
(cond [(null? nl) ...]
[else (... (car nl)... (cdr nl))])))
We definitely know more about the data. (car nl) in the nested-list-template is of type NestedElem. Therefore we can fill up some ...s with calls to templates that deal with that kind of data. In the same vein, we can wrap recursive calls around expressions of a datatype we know of.
; NestedElem -> ...
(define nested-elem-template
(lambda (ne)
(cond
[(atom? ne) (atom-template ne)]
[else (nested-list-template ne)])))
; Atom -> ...
(define atom-template
(lambda (atom)
(cond [(number? atom) ...]
[(symbol? atom) ...])))
; NestedList -> ...
(define nested-list-template
(lambda (nl)
(cond [(null? nl) ...]
[else (... (nested-elem-template (car nl))
... (nested-list-template (cdr nl)))])))
Now we can "fill in the blanks".
We can "filter", "map", and "fold" over this data structure. All those can be defined using the template as a scaffold.
Note 1: Your HW asks you to do multiple tasks:
remove the symbols
sum up the numbers
cons the sum onto every list
Don't try to do everything in a single function. Delegate into multiple helper functions/traversals.
Note 2: I did not model the output type. It's the same as input type except that Symbol is no longer an atom.

Racket find shared elements between lists

I'm trying to create a specific response for a given list if it has shared elements with another list. As in if I have a list that is (My name is John) and I have another list of (John Adam Jacob) I would want the first list to be able to see that John is in the second list, and be able to print something along the lines of (this is a known name) or something similiar.
The code I have thought of uses map, and member.
(define (specific-reply user-list)
(cond (member (map (lambda (user-list)) '(John Adam Jacob)))
(write (this is a known name))
(else
(write (this is not a known name)))))
I'm extremely knew to both racket and scheme however and I haven't really gotten it to compile yet so I think I'm largely off.
Any help would be greatly appreciated.
You don't need to complicate the problem if your task is to just find if a is a member of (a b c),
Here's a piece of Scheme code that can tell if a is a member of lat.
It's just a simple recursive function that compares each element of lat with a for a match.
(define member?
(lambda (a lat)
(cond
((null? lat) #f)
((eq? a lat) #t)
(else
(member? a (cdr lat))))))
If you want to take this further and find the intersection of two lists, we can do something like this!
(define intersect
(lambda (set1 set2)
(letrec
((I (lambda (set)
(cond
((null? set) (quote ()))
((member? (car set) set2)
(cons (car set)
(I (cdr set))))
(else (I (cdr set)))))))
(I set1))))
You can use this code as such. Tested from guile compiler
(begin
(display (intersect `(1 2 3) `(1 3 4 5 2)))
(newline))
>> (1 2)
EDIT
I recommend you read The Little Schemer and the The Seasoned Schemer to get more familiar with these kind of concepts
Why not use set in racket:
(define (list-intersect-2 lst1 lst2)
(set->list
(set-intersect (list->set lst1)
(list->set lst2))))
For a solution that takes one or more lists:
(define (list-intersect lst1 . lstn)
(set->list
(foldl set-intersect
(list->set lst1)
(map list->set lstn))))
(list-intersect '(1 2 3) '(2 3 4) '(3 4 8))
; ==> (3)
One can also use built-in functions filter and member to find intersection of 2 lists:
(define (intersection l1 l2)
(remove-duplicates
(filter (λ (x) (member x l1))
l2)))
Above checks each item of l2 to keep it only if it is a member of l1 also.
One can also use for/list to check each element and return a list of common items:
(define (intersect l1 l2)
(remove-duplicates
(for/list ((i l1)
#:when (member i l2))
i)))
Both above function remove duplicates. Just avoiding use of remove-duplicates may result in different result if simply the order of l1 and l2 is interchaged. If one wants that the repeated elements to come repeatedly in outcome list, one can use following function in which common items are removed before proceeding:
(define (intersection2 l1 l2)
(let loop ((l1 l1)
(l2 l2)
(ol '()))
(cond
[(empty? l1) (reverse ol)]
[(member (first l1) l2) ; first item of l1 is common
(loop (rest l1) ; loop with rest of l1
(remove (first l1) l2) ; remove common item from l2
(cons (first l1) ol))] ; add common item to outlist
[else
(loop (rest l1)
l2
ol)])))
Testing:
(intersection2 '(2 4 2 7 2 10) '(10 2 9 2 0 11))
Output:
'(2 2 10)

How to reverse the order of elements of a list in Scheme

I got a function to reverse the order of the elements in a list, such as
(define (rvsl sequence)
(foldl (lambda (x y)
(cons y x))
'() sequence))
However, when I ran it in DrRacket with the input
(rvsl (list 2 3 4))
DrRacket told me this
cons: second argument must be a list, but received empty and 2
Could anybody please give me some ideas to solve it?
Thanks in advance!
The problem with your code is that you're passing the parameters in the wrong order - when using cons to build a list, the first parameter is the new element we want to stick at the beginning of the list, and the second one is the list we've built so far.
Having said that, reversing a list using foldl is a bit simpler and you don't need to use append at all - in fact, it's a bad practice using append when cons suffices:
(define (rvsl sequence)
(foldl cons
'()
sequence))
Why this works? let's rewrite the function being more explicit this time:
(define (rvsl sequence)
(foldl (lambda (current accumulated)
(cons current accumulated))
'()
sequence))
Now we can see that the lambda procedure receives two parameters: the current element in the input list, and the accumulated value so far - good parameter names make all the difference in the world! this is much, much clearer than calling the parameters x and y, which says nothing about them.
In this case, we just want to cons the current element at the head of the accumulated value (which starts as an empty list), hence producing a reversed list as the output. Given that the lambda procedure receives two parameters and passes them in the same order to cons, we can simplify the whole thing and just pass the cons procedure as a parameter.
Here is a simple version, using an internal iterative procedure.
(define (rev lst)
(define (iter accum lst)
(if (null? lst)
accum
(iter (cons (car lst) accum)
(cdr lst))))
(iter '() lst))
You don't have to use foldl or anything else, actually, to define the rev function; the rev function itself is enough:
(define (rev ls) ; rev [] = []
(cond ; rev [x] = [x]
((null? ls) ls) ; rev (x:xs)
((null? (rest ls)) ls) ; | (a:b) <- rev xs
(else ; = a : rev (x : rev b)
(cons (first (rev (rest ls)))
(rev (cons (first ls)
(rev (rest (rev (rest ls))))))))))
(comments in equational pattern-matching pseudocode). Derivation and some discussion here.
(edit: that's obviously a toy code, just to hone your Scheme-fu).

Resources