Title: CS1321: Introduction to Programming
1CS1321Introduction to Programming
- Georgia Institute of Technology
- College of Computing
- Module 7
- Lists
2Two Concepts
- They are 1. lists (or cons cells)
- - and -
- 2. recursion
- They are highly interrelated, just watchand see!
3Lets build off this idea of structures weve
seen...
In Scheme, and indeed most programming languages,
there exist data definitions that reference
themselves within their own definitions.
What?
4I Present to You Exhibit 1
Think of Russian Matryoska dolls - a doll that
has a doll inside it, that has a doll inside it,
and so on
Each doll has its own height, and might contain
another doll. But at some point, the chain comes
to an end. How can this be modeled in Scheme?
5The Example
Data Analysis and Definitions (define-struct
matryoska-doll (height next-doll)) That much is
easy, but heres the Analysis portion that
reveals a problem
6An Example
Data Analysis and Definitions (define-struct
matryoska-doll (height next-doll)) That much is
easy, but heres the Analysis portion that
reveals a problem
See the dilemma?
a matryoska-doll is a structure where
height is a number next-doll is a
matryoska-doll
7An Example
Data Analysis and Definitions (define-struct
matryoska-doll (height next-doll)) That much is
easy, but heres the Analysis portion that
reveals a problem
This is self-referential. When does such
a definition ever end?
a matryoska-doll is a structure where
height is a number next-doll is a
matryoska-doll
8An Example
We can work around this by saying that
next-doll is either a symbol, like end, or
its a matryoska-doll. Data Analysis and
Definitions (define-struct matryoska-doll (height
next-doll)) a matryoska-doll is a structure
where height is a number next-doll
is either a
matryoska-doll, or the
symbol end
9An Example
Data Analysis and Definitions (define-struct
matryoska-doll (height next-doll)) a
matryoska-doll is a structure where height
is a number next-doll is either
a matryoska-doll, or
the symbol end
(make-matryoska-doll 10
(make-matryoska-doll 9
(make-matryoska-doll 8 end)))
10An Example
Data Analysis and Definitions (define-struct
matryoska-doll (height next-doll)) a
matryoska-doll is a structure where height
is a number next-doll is either
a matryoska-doll, or
the symbol end
(make-matryoska-doll 10
(make-matryoska-doll 9
(make-matryoska-doll 8 end)))
11An Example
We know that a matryoska doll is made of two
things
? ?
12An Example
We know that a matryoska doll is made of two
things
?
height
13An Example
We know that a matryoska doll is made of two
things
The next doll structure or the symbol end
height
14An Example
(make-matryoska-doll 10
(make-matryoska-doll 9
(make-matryoska-doll 8 end)))
10
9
Another doll structure or symbol
15An Example
(make-matryoska-doll 10
(make-matryoska-doll 9
(make-matryoska-doll 8 end)))
10
9
8
end
We can visualize this another way. The
matryoska-doll data structure is considered to be
recursive because it is self-referential.
16Another Example...
Everyones seen a line at a bank Lets ask some
questions about them.
17Is an empty line still a line?
This is a philosophical question, as well as a
computing problem...
18Is an empty line still a line?
Put another way, we ask if theres a something in
nothing.
Well, nothing is certainly something. We saw
this with our matryoska dolls with the symbol
end. We have to use something to mean nothing.
J.P. Sartre contemplating nothingness
19Is an empty line still a line?
Yes. An empty line is still a line. Its just
empty.
20Can a line have just one person in it?
Yes.
Whats behind that one person?
The empty line, which is still a line
21So does anything change as more people get in
line?
Not really. As people are added or removed from
a line, we still have a line.
WHY?
22Because a line consists of 1) The empty line
or 2) At least
one customer and a irritated,
ticked off line behind them.
23No matter what the size of our line, which
customers can the teller deal with?
The first customer. Thats all that is
accessible.
So how does the teller get to the rest of the
line?
By dealing with the first customer.
Why am I highlighting first and rest?
24Lets translate Lines into Lists!
A list is a standard computing concept in most
modern programming languages. In its simplest
form, its similar to the concept of a line.
- A list is either
- The empty list
- At least one ??? and a list of ???.
- A line is either
- The empty line
- At least one person and a line behind them.
25Lets translate Lines into Lists!
A list is a fairly central computing concept to
most of todays modern languages. In its
simplest form, its similar to the concept of a
line.
Whats the ??? mean? Lists arent limited to one
data type!
- A list is either
- The empty list
- At least one ??? and a list of ???.
- A line is either
- The empty line
- At least one person and a line of people.
26Visually
A List with at least One Item
A List with at least One Item
The Empty List
Eggs
Eggs Milk Sausage Butter Cheese .
We add more stuff to our list as time goes on.
27Understanding Schemes List
The fundamental unit of a List is NOT a
structure, per say. It is the
CONS CELL
28The Cons Cell
The Cons Cell is one of Schemes first and best
known data structure. A cons cell, much like a
structure, is divided into different components
or fields. Unlike structures, cons cells consist
of two and only two components.
Visually, we represent the cons cell as
29The cons cell predates structures and is not a
structure
A cons cell is a much older artifact of Scheme
and its predecessor computer language Lisp.
You do not create a cons cell as you would a
structure. You do not access cons cell data as
you would access data from a structure.
30The Cons Cell continued
We give each component a name
rest
first
31Still more about Cons Cells
To access the two components, we use two scheme
functions provided for you (first ltcons cell
listgt) ? retrieves the data in the
first portion of the cons cell (rest
ltcons cell listgt) ? retrieves the data in
the second portion
32How to work with Cons Cells
(cons ltitemgt ltitemgt) ? Creates cons cells (first
ltcons cellgt) ? Accesses the front of the
cons cell (rest ltcons cellgt) ? Accesses the
back of the cons cell (cons?
ltitemgt) ? Tells whether or not the item is
a cons cell
33Further Restrictions on Cons Cells
In Beginning through Advanced Scheme Modes,
certain restrictions are placed on cons and
associated functions 1) Cons Cells can ONLY
be used to create lists 2) the
functions first, rest, cons? exist only
in these language levels for readability
purposes.
34Whats a List?
List - a self-referencing data structure.
A data structure that contained within it an item
of with the same definition.
35What can I put inside a list and why should I use
them?
Lists are used to store a variety of data. The
concept of a list is very generic. We can create
lists of numbers, lists of symbols, list of
structures, etc. Lists fall into a class of data
structures known as Dynamic Data Types. We can
create lists that store as much or as little
information as we need. We can also modify the
number of items stored within the list as we go.
36Before we build with cons cells,
we should look over the Data Definition of a
list A list consists of 1) The
empty list, empty, or 2) (cons d lod)
where d is a ??? and lod is a list of ???
37Before we build with cons cells
empty is special and denotes the end of a list.
Note that its not the same as empty.
Before we can build a list out of our cons cells,
we should look over the Data Definition of a
list A list consists of 1) The
empty list, empty, or 2) (cons d lod)
where d is a ??? and lod is a list of ???
38Before we build with cons cells
Empty is a special symbol that denotes the end
of a list. Note that its not the same as empty.
This is just a place holder for data types that
were going to store in our list. Lets work
through some concrete examples
Before we can build a list out of our cons cells,
we should look over the Data Definition of a
list A list consists of 1) The
empty list, empty, or 2) (cons d lod)
where d is a ??? and lod is a list of ???
39Data Definition Example list-of-numbers
A list-of-numbers consists of 1) The
empty list, empty, or 2) (cons n lon)
where n is a number and lon is a list
of numbers
40Data Definition Example list-of-symbols
A list-of-symbols consists of 1) The
empty list, empty, or 2) (cons s los)
where s is a symbol and los is a list
of symbols
41Putting things together with cons cells
Creating things with cons cells is fairly
straight-forward. We use the built-in function
cons. cons takes in two arguments A piece of
data to store in the list and a list to store it
on.
Lets walk through an example or two!
42Building a List of Numbers
(cons 1 empty)
43Building a List of Numbers
(cons 1 empty)
44Building a List of Numbers
(cons 1 empty)
1
empty
45Adding more
(cons 1 (cons 2 (cons 3 empty)))
1
2
3
empty
46Another (easier to draw) visualization
(cons 3 empty)
empty
3
47Another (easier to draw) visualization
(cons 2 (cons 3 empty))
2
3
empty
48Another (easier to draw) visualization
(cons 1 (cons 2 (cons 3 empty)))
49Working with the List
(first (cons 1 (cons 2 (cons 3 empty))))
50Working with the List
(rest (cons 1 (cons 2 (cons 3 empty))))
51Other functions that may be useful
(empty? ltvaluegt) (list? ltvaluegt)
Returns whether or not the value is the empty list
Returns whether or not the value is a cons cell
list
52How do we process a list?
- A lists is built of cons cells, and we use the
accessors first and rest to see the data inside
the list. - Lists are of arbitrary length. We can write a
function that can consume a list with one item,
twenty items, or no items (the empty list).
53How do we process a list?
- The list lends itself very well to an idea called
recursion.
54Recursion
55Definition
Recursion (rÎ-kûr-zh-n) n. See Recursion. --
The New Hackers Dictionary
56Recursion Defined
- Recursion is when a function calls itself.
- Powerful mechanism for repetition.
- Makes algorithms more compact and simple.
- Function actually calls a clone of itself.
- Very useful, especially for dynamic data types.
57Three Characteristics of Recursion
- 1. Function calls itself recursively
- Has some terminating condition
- Moves closer to the terminatingcondition.
Know this!!!
58So how do we process a list?
- The list lends itself very well to an idea called
recursion. - We have a natural termination condition that
allows us to stop processing - the empty list
- We have a way to move closer to the termination
condition - (rest )
59Processing a list of numbers
Lets see recursion in action! Problem
Definition Write a function sum-list that
consumes as a parameter a list of numbers and
returns the sum of the numbers in our list.
60The Design Recipe Approach
Data Analysis Definitions a
list-of-numbers consists of 1) the empty
list, empty, or 2) (cons n lon) where n
is a number and lon is a list of
numbers
61The Design Recipe Approach
Data Analysis Definitions a
list-of-numbers consists of 1) the empty
list, empty, or 2) (cons n lon) where n
is a number and lon is a
list-of-numbers
Note this recursive data definition. i.e. the
definition refers back to what we are defining.
62 Contract sum-list list-of-numbers ?
number Purpose This function sums all
numbers in a list of
numbers. Examples (sum-list (cons 1 (cons 2
(cons 3 empty)))) should
produce 6 (sum-list (cons 3
(cons 4 (cons 5 empty))))
should produce 2
63The Template
The template becomes a critical component of our
design recipe for recurring on data definitions.
The template not only reflects your data
definitions, but also the fact that your data
definition is recursive!
64The Template
Template (define (process-list-of-numbers
in-num-list)
Nothing strange so far
65The Template
Template (define (process-list-of-numbers
in-num-list) (cond ((empty?
in-num-list) )
- Remember, your data definition is that
- list-of-numbers is either
- The empty list
- (cons n lon) where n is a number
- and lon is a list of numbers
66The Template
Template (define (process-list-of-numbers
in-num-list) (cond ((empty?
in-num-list) ) (else
(first in-num-list)
(rest in-num-list))))
67The Template
This is almost right, but lets indicate how we
process the rest of the list.
Template (define (process-num-list
in-num-list) (cond ((empty?
in-num-list) ) (else
(first in-num-list)
(rest in-num-list))))
68The Template
Template (define (process-list-of-numbers
in-num-list) (cond ((empty?
in-num-list) ) (else
(first in-num-list)
(process-list-of-numbers
(rest in-num-list)))))
Thats our recursive call!
69The Function!
Definition (define (sum-list in-list)
(cond ((empty? in-list) 0) (else
( (first in-list)
(sum-list (rest in-list)))))) Tests ( 6
(sum-list (cons 1 (cons 2 (cons 3 empty))))) ( 2
(sum-list (cons 3 (cons 4 (cons 5 empty)))))
70The Function!
Did you notice how similar the actual function is
to process-list-of-numbers?
Definition (define (sum-list in-list)
(cond ((empty? in-list) 0) (else
( (first in-list)
(sum-list (rest in-list)))))) Tests ( 6
(sum-list (cons 1 (cons 2 (cons 3 empty))))) ( 2
(sum-list (cons 3 (cons 4 (cons 5 empty)))))
71Stack Model of Evaluation
It is absolutely vital to note that although you
are recurring through your list throughout your
function, nothing ACTUALLY happens to your list.
The list that existed before you executed your
function exists in its entirety after the
function ceases to execute. And to prove it.
72Lets see why
73Example
What do you suppose happens when we write a
recursive function
(define (sum-list in-list) (cond (empty?
in-list) 0) else ( (first in-list)
(sum-list (rest in-list))))
And then call it with (sum-list (cons 1 (cons
2 (cons 3 empty))))
74Example
When we first enter the function, we have
(sum-list (cons 1 (cons 2 (cons 3 empty))))
75We postpone the return result, and recur
(sum-list (cons 1 (cons 2 (cons 3 empty)))) (1
(sum-list (cons 2 (cons 3 empty))))
The function returns 1 whats returned from
the next recursive call. What happens next in
memory?
FYI We use in-fix notation for readability
76Note the growth of the activation stack, and
the possible copying of data.
Potentially, we have
(sum-list (cons 1 (cons 2 (cons 3
empty)))) (1 (sum-list (cons 2 (cons 3
empty))))
Recall how in parameters work. So this
means each in-list reference is unique?
77(sum-list (cons 1 (cons 2 (cons 3
empty)))) (1 (sum-list (cons 2 (cons 3
empty)))) (1 2 (sum-list (cons 3 empty)))
This continues, and each frame needs a
little more memory
78(sum-list (cons 1 (cons 2
(cons 3 empty)))) (1 (sum-list
(cons 2 (cons 3 empty)))) (1 2
(sum-list (cons 3 empty))) (1 2
3 (sum-list empty))
in-list
empty
This continues until we reach a termination
79(sum-list (cons 1 (cons 2
(cons 3 empty)))) (1 (sum-list
(cons 2 (cons 3 empty)))) (1 2
(sum-list (cons 3 empty))) (1 2
3 (sum-list empty)) (1 2 3 0)
in-list
empty
This continues until we reach a termination
80Further Reading An Important Disclaimer
What we saw with unique copies of the list being
created in each call is not necessarily how
Scheme would handle this. Rather, we just used
this to learn about references, and how we point
to cons structures.
Its actually possible, and far more efficient,
to just have a single copy of the data, and have
many unique pointers into the data set.
81in-list
in-list
in-list
in-list
82This global place in memory is called
the heap or memory heap. Its a large area
available for use by code in execution.
Usually, the heap is used to hold variables,
something weve not seen yet, because we are
using a completely functional approach to
programming. Another other variables or values
created inside the method calls are local to the
method. They are stack variables that do not
persist when the method returns.