What is the result of this in scheme: (cdr '((a b c d))) - list

Isn't it supposed to be (a b c d) ??
When I try it on Racket it gives me () .

'((a b c d)) is a list, containing only one element, that is the four-element list (a b c d). So if you get the car of it, you obtain as result (a b c d), while the cdr produces correctly the empty list ().

How would you create such a list using cons?
(cons (cons 'a (cons 'b (cons 'c (cons 'd '()))))
'())
or
(cons '(a b c d) '())
cdr returns the second element of the given pair, so it returns '().

Related

Racket/Scheme - checking to see if a list is a sublist of another list

I'm new to coding in racket, but I wanted to define a procedure that checks to see if a given list is a sublist (or part of) another list.
This is my code so far:
(define prefix?
(lambda (lst1 lst2)
(cond
((equal? lst1 lst2) #t)
((null? lst2) #f)
(else (prefix? lst1 (reverse (rest (reverse lst2))))))))
(define sublist?
(lambda (lst1 lst2)
(cond
((prefix? lst1 lst2) #t)
((null? lst2) #f)
(else (prefix? lst1 (rest lst2))))))
I've tried most cases and it works the way it's supposed to but when I tried this test case:
(sublist? '(a b d) '(a b c a b d e))
It returns #f when it's supposed to return #t
I tried tracing the sublist? procedure but it isn't returning me any useful information.
Is there a logic error in my code?
There is a logic error. The default case of sublist? should call sublist?, but instead calls prefix? so your prefix? will only be true if the match is either in index 0 or 1.
Also you have created a rather complex prefix?. Instead of comparing one by one element until any of them are empty you do a O(n) removal of the last element until you have a empty list before returning #f even if the two first elements are different. I would have compared the first elements and then recurred with rest in both args until either list is empty. Which one depends on the result and eg. (prefix '(a b) '(w a d f s)) will stop computing after the very first check between a and w.
try this:
(define sub?
(lambda (l sub)
(define test (lambda (x) (equal? x sub)))
((lambda (s) (s s l test))
(lambda (s l k)
(or (k '())
(and (pair? l)
(s s (cdr l)
(lambda (r)
(or (test r)
(k (cons (car l) r)))))))))))
(sub? '(a b c a b d e) '(b d e) )
(sub? '(a b c a b d e) '(c a b) )
(sub? '(a b c a b d e) '(a b c) )
(sub? '(a b c a b x e) '(a b d) )

How to create a dictionary mapping on custom dictionary in Racket?

I have defined dictionary as this judgment in BNF grammar:
d ::= () (any boolean) (list cons d d)
Meaning, dictionaries are empty, or (any boolean) or a list of such pairs.
If I want to create a mapping, say "a true", how do I do it?
If I do
(define-values (d) (values '(a true)))
it just creates a new d, doesn't map to previous judgment d defined.
IIUC you want your dictionary to be just an association list:
(define d (list (cons 'x #t) (cons 'y #f)))
Depending on how are you going to implement the add operation you could either set! a new mapping:
(set! d (cons (cons 'z #t) d))
Or just create a new list (preferred):
(define d (list (cons 'z #t) (cons 'x #t) (cons 'y #f)))
Either way, the dictionary d will have the new mapping in the expected format:
'((z . #t) (x . #t) (y . #f))

Scheme pair construction

I am trying to understand pair construction and representation.
Let's take a look at the following results:
(length (cons '(a b) '(d e f)))
=> 4
Now let's switch the order:
(length (cons '(d e f) '(a b)))
=> 3
but
(length (car (cons '(d e f) '(a b))))
=> 3
Could you please explain the results above?
What is the difference between car and cdr?
Remember that cons simply sticks together two things, for historical reasons the first one is referred to as car and the second one as cdr.
If the second one happens to be a proper list, then the result is also a list. Hence a list is defined as the result of consing one element with the result of consing one element ... and so on, until we reach the empty list '(). For example:
(cons 1 (cons 2 (cons 3 '())))
=> '(1 2 3)
When dealing with lists, think of car as the first element of the list and cdr as the rest of the elements, and cons adds one more element at the head of the list - that element can be anything, including another list. It just gets added at the head, the lists are not "merged" (we use append for that). Take a look:
(car '(1 2 3))
=> 1
(cdr '(1 2 3))
=> '(2 3)
Now, regarding your examples - the first one adds '(a b) as the first element of a list, where the rest is '(d e f), so we now have a 4 element list, like this:
(cons '(a b) '(d e f))
=> '((a b) d e f)
Similarly for the second example: we add the first element '(d e f) to the rest of the elements '(a b), and we get a 3 element list:
(cons '(d e f) '(a b))
=> '((d e f) a b)
Finally, if we call car on the above list, we get its first element - which happens to be '(d e f), and clearly it has 3 elements:
(car (cons '(d e f) '(a b)))
=> '(d e f)

Every other letter in a list? LISP

I am relatively new to LISP and am trying some new things for a Lisp program I am trying to create for a presentation.
I need to be able to print every other character in a list, for example, (A B C D E F) would return (A C E) .. but I am getting easily confused...
I am normally program Java, so this comes kind of different to me.
I am trying to program this using purely recursion.. So something along the lines of....
(defun every-other (lst)
(cond ((null lst) 0)
(( **** now this is where I get confused as to what I should do..
I've tried adding a counter to only remove even numbered elements, but I think I implemented the counter wrong, I also tried remove(cadr lst) lst, but that would only return zeros...
any help would be greatly appreciated..
Thanks!
Since you say you want it to be done recursively, just think it through case by case.
The list is null -> return the empty list [the empty list is '()].
Otherwise the list is not null -> In this case you want to build a new list containing
the first element, skip the second element, then grab
every-other element of the remaining list.
Turning this case analysis into code looks something like this:
(defun every-other (lst)
(cond
;; If the list is null return the empty list.
((null lst) '())
;; If the list is not null, construct [cons] a new list with the first element of lst
;; and every-other element of the list after the first two elements [rest returns the
;; list without the first element, so we can just use it twice].
(t (cons (first lst) (every-other (rest (rest lst)))))))
Now going through the evaluation of this code should look something like this:
(every-other '(a b c d e f))
=> (cons 'a (every-other '(c d e f)))
=> (cons 'a (cons 'c (every-other '(e f))))
=> (cons 'a (cons 'c (cons 'e (every-other '())))
=> (cons 'a (cons 'c (cons 'e '())))
=> (cons 'a (cons 'c '(e)))
=> (cons 'a '(c e))
=> '(a c e)
For fun, a loop-based solution:
(defun every-other (lst)
(loop
for i in lst
for keep = t then (not keep)
if keep collect i))
Just use a loop.
(loop :for c :in '(a b c d e f) :by #'cddr
:collect c)
:By in a for-in clause sets the stepping function (default is #'cdr). In order to get every other element, step two steps each time. Cddr is a shortcut for applying cdr two times.
(defun aaa (x)
(aa (length x) x))
(defun aa (n x)
(cond ((null x) nil)
((evenp (- n (length x))) (cons (car x) (aa n (cdr x))))
(t (aa n (cdr x)))))
This is a stupid case lol~
shorter recursive solution:
(defun every-other (l)
(unless (null l)
(cons (first l) (every-other (cddr l)))))

Get result with list

;How to get the value of 'a' in 'b'?
;Not want to assign the letter 'a' in 'b' want the value contained in 'a'
(define a 5)
(define c '(a c))
(define b (car c))
(display b)
(define a 5)
(define c (list a 'c))
(define b (car c))
(display b)
' is equivalent to the quote procedure. So '(a c) => (list 'a 'c)
See: http://www.gnu.org/software/mit-scheme/documentation/mit-scheme-ref/Quoting.html#Quoting
Or, using your original code, are you asking how you would (eval b (the-environment))?