



Study with the several resources on Docsity
Earn points by helping other students or get them with a premium plan
Prepare for your exams
Study with the several resources on Docsity
Earn points to download
Earn points by helping other students or get them with a premium plan
An in-depth explanation of list procedures such as cons, cdr, car, cadr, list-ref, and append in scheme. It also covers the concept of data abstraction, specifically point data abstraction, which includes constructors, selectors, and contract. The document demonstrates how to create procedures like make-point, get-x, get-y, add-point, and left-of?. It also discusses the importance of maintaining the abstraction and avoiding abstraction violations.
Typology: Slides
1 / 5
This page cannot be seen from the preview
Don't miss anything!




Lecture 5: List Procedures and Data Abstraction
Review of list procedures:
cons: (cons elem lst) car: (car lst) Æ first element cdr: (cdr lst) Æ the rest of the elements (all but first) cadr: (car (cdr lst))Æ second element list-ref: (list-ref lst k)Æ kth element of lst (remember zero-based indexing) list: (list elements)Æ (elements) append: (append lst1 lst2)Ælist of all elements in lst1 and lst2, ordered
list-copy: given a list, it makes a copy of the exact list and returns it.
Create a procedure called list-copy. Write a plan: Base case: nilÆnil Recursive case: (cons (car lst) (list-copy (cdr lst)))
Consider (cons 1 (2 3)) Æ (1 2 3) when trying to understand the above.
Now we define.
(define (list-copy lst) (if (null? lst) nil (cons (car lst) (list-copy (cdr lst)))))
The last primitive procedure above, cdr, is “cdr-ing” down the list lst.
Create a procedure called n-copies that will make n copies of an element and enclose them within a list.
Write a plan: Base case: copies = 0 Æ nil Recursive: (cons elem (n-copies elem (- copies 1)))
Let’s analyze from the innermost procedure out. We are taking one less than the amount of copies we need, keeping the element unchanged, performing the n-copies procedure on that unchanged element for 1 fewer copies, and adding one identical element to the front of the result of the n-1 copies list.
(define (n-copies elem copies) (if (= copies 0) nil (cons elem (n-copies elem (- copies 1)))))
Create a procedure called reverse to reverse a list. (1 2 3) => (3 2 1)
Write a plan: Base case: nilÆ nil Recursive case: stick (car lst) on the end of (reverse (cdr lst)) In scheme terms, (append (reverse (cdr lst)) (list (car lst)))
(define (reverse lst) (if (null? lst) nil (append (reverse (cdr lst)) (list (car lst)))))
Change the above recursive process to an iterative process.
(define (reverse-helper lst answer) (if (null? lst) answer (reverse-helper (cdr lst) (cons (car lst) answer))))
(define (reverse lst) (reverse-helper lst nil))
The following is the iterative process that occurs through this procedure:
(reverse (list 1 2 3)) (reverse-helper (1 2 3) ( )) (reverse-helper (2 3) (1)) (reverse-helper (3) (2 1)) (reverse-helper ( ) (3 2 1))
Create the procedure append that glues two lists together.
Write a plan: Base case: lst1 is null Æ lst Recursive: (cons (car lst1) (append (cdr lst1) lst2))
Point Data Abstraction It is important to implement the user-defined type in the following order:
Takes in two numbers and returns a point, so the types are
number, number Æ point
point is a user-defined type
(define p1 (make-point 5 7)) Æ p1 is a point at (5,7) p1 prints out as: (5 7)
(define (get-x p) (car p)) (define (get-y p) (cadr p))
We want to add p1 and p2 together.
(define (add-point p1 p2) (make-point (+ (get-x p1) (get-x p2)) (+ (get-y p1 (get-y p2))))
(define v (add-point p1 p2) v => (10 14)
Type of add-point is: point, point -> point
“client” of data abstraction, as mentioned before, is the user. This user is not aware of lists used to create the function add-point or the function get-x. This is important to recognize.
Create a procedure that determines if a point is to the left of another point:
(define (left-of? p1 p2 ) (< (get-x p1) (get-x p2)))
Evaluating left-of? in an example: (left-of? (make-point 3 4) (make-point 1 2)) ;Value: #f
append: list, list Æ list left-of?: point, point Æ Boolean
*Above is the second mention of derived types. Point is a type we “derived” to talk about the function left-of?, which determines if the first point is left of the second point. The return value is a Boolean. Types help to write code and to check code.
Abstraction Violation
(define (left-of? p1 p2) (< (car p1) (car p2)))
The above depends on specific implementation. We cannot use car, because car could have been predetermined as a different procedure used to find the y value if the coordinates in the definition of get-y had been written as (y x) instead of (x y).
A line must be imagined to exist between already-created constructors and selectors, and the contract between the two.
If you assume you know the implementation of constructor/selector, problems arise, because the coding in constructors and selectors may change. This change is unknown to “user”, so use contract…not abstraction violation.
Here’s a visual:
When we know what the list looks like, When we don’t know what the list looks p1 like, we can picture as a cloud:
we can picture it like this:
p 5 7
The rest of the notes consists of defining stacked abstractions (defining new abstractions with previously-defined abstractions). The solutions are posted at the solutions to lecture 5, posted on the server.
Layer abstraction: we have the definition of points, but we want to keep going. Construct an abstraction entitled “segment” to define a line segment, which is constructed from a pair of end points.