Lecture 8 Slides - Composite Data Types

1 of 46

Lecture 8

Composite Data Objects - Representing the Real World

2 of 46

Logistics and Week Ahead

For some - Ethics Module 3 - Accountability

  • Monday - Booleans + Composite Data (Ex 3 Posted)
  • Wednesday - Manipulating Composite Data (Pre-Recorded + MQ6) + Tutorial 3
  • Friday - Q1 Review (MQ 7) (Ex 3 Due)

Reminders:

  • Q1 next Monday!
  • Take 10 seconds each week to check your grades in the course. edSTEM posts whenever grades go live. If you're expecting a participation grade and don't get it, fill out the petition form. Only things missing should be: Ethics 1&2; Ex 2 (today at 5pm)

3 of 46

Quiz 1 - 10/13 Monday

  • In-person here in the Auditorium (ANU Students should register to take the exam at the ANU Testing Center by the end of the day today)
  • Taken on the LDB on your personal computer; details on how to set it up are on Quiz 1 page.
  • During your assigned class time; you MUST attend the one you're registered for
  • You must be able to connect to eduroam
  • Three Types of Problems:
    • What's the type of this expression?
    • Here's a program; here's what we want to get out of it; here's what we get; fix it
    • Write a valid test for the given function definition
  • Covers everything up to and including Lecture 9 (Manipulating Composite Data)
  • You do NOT need to memorize all of the functions (you get a glossary)
  • You DO need to know the Rules of Execution and Special Forms.

4 of 46

Boolean expressions

5 of 46

Boolean objects - A new data type

  • Racket code is made up of expressions
    • (= a b) is an expression
  • And all expressions produce outputs (data objects) when they’re executed
    • So then what kind of data object does (= a b) produce?
  • Answer: a truth value true or false
    • These are named Booleans after George Boole, who invented Boolean Algebra, an early form of symbolic logic

6 of 46

Boolean constants

  • Racket has two magic data objects that are used to represent the answers to questions
    • They’re named true and false.
  • For historical reasons, you can type them a few different ways:
    • True: true, #true, #t
    • False: false, #false, #f
  • You can use any of these
    • We’ll generally use true and false in slides
    • But DrRacket always prints them in # format

7 of 46

A new kind of expression: if

(if test consequent alternative)

  • If test is true,
    • Then execute and return consequent
    • Otherwise, execute and return alternative
  • Some useful built-in tests
    • (string=? a b)�Checks if a and b are the same string
    • (= a b)

Checks if a and b are the same number

    • (> a b), (<= a b), etc.

Compares numbers

;; absolute-value: num -> num

;; Removes the sign from a num

> (define absolute-value

(λ (n)

(if (> n 0)

n

(- n))))

> (absolute-value 5)

5

> (absolute-value -5)

5

Note: absolute value is already in Racket and is called abs. We just use it here because it’s a simple example.

8 of 46

new rules of execution

9 of 46

Rules of computation in Racket

Look at the expression

  • If it’s a constant (i.e. a number or string), it’s its own value
  • If it’s a variable name (i.e. a word, hyphenated phrase, etc.), look its value up in the dictionary
  • Parentheses? (Check if it’s one of the special cases from the next slide)
  • Otherwise it’s a function call
    • (func-expression arg-expression1arg-expressionn)
    • Execute all the subexpressions�(func-expression and arg-expression1 through arg-expressionn)
    • Call the value of func-expression, passing it the values of arg-expression1 through arg-expressionn as inputs
    • Use its output as the value of the expression

10 of 46

Special cases: Rules of computation in Racket

If it starts with define

(define name value-expression)

  • Run value-expression
  • Assign its value to namein the dictionary

If it starts with λ or lambda:

(λ (name1namelast) result-expression)

  • Make a function
    • That names its inputs�name1namelast
    • And returns the value�of result-expression(presumably using those names)

If it starts with the the word local

(local [(define name1 value1) � …� (define namelast valuelast)]� result-expression)

  • Run the value expressions
  • Substitutes their values for their respective�names in result-expression
  • Runs the substituted result-expression
  • Returns its value

If it starts with if:

(if test consequent alternative)

  • Run test
  • If it returns true, run consequent and return its value
  • Otherwise run alternative and return its value

11 of 46

Some other built-in tests

  • (number? value), (string? value),�(integer? value), (procedure? value)

Tests what kind of data value is

  • (odd? number), (even? number)

Tests whether a number is odd or even

  • (and test1 test2testn)�(or test1 test2testn)�(not test)

Combines tests into more complicated tests

Note: Racket sometimes calls "functions" a different word: procedures. Functionally, they're the same in our class, but this function here, which tests to see if the given value is a function is actually named procedure? Rather than function?

12 of 46

Examples

Suppose we say:

(define a 7)

(define b 8)

(define c 9.5)

What are the values of:

> (> a b)

>

> (< a b)

>

> (not (= b c))

>

> (integer? c)

>

> (odd? a)

>

> (and (< 5 a)

(< a 10))

>

13 of 46

Examples

Suppose we say:

(define a 7)

(define b 8)

(define c 9.5)

What are the values of:

> (> a b)

> #false

> (< a b)

> #true

> (not (= b c))

> #true

> (integer? c)

> #false

> (odd? a)

> #true

> (and (< 5 a)

(< a 10))

> #true

14 of 46

Executing a Boolean expression

Evaluating tests is really just normal function* execution

(and (< 5 a)� (< a 10))

  • First, execute (< 5 a)
    • Call < with 5 and 7 as inputs
    • < returns true
  • Then call (< a 10)
    • Call < with 7 and 10 as inputs
    • < returns true
  • Call and with true and true as arguments
    • (this part is a little more complicated, but that won’t matter until CS 211)
  • And returns true

*Truth in advertising: and isn’t actually a function, it’s a special form. So this slide is a lie. But it’s a useful lie.

15 of 46

Predicates (question answer-ers)

  • Functions that return Booleans, e.g. = or odd?, are called predicates
    • They can be thought of as tests or question answer-ers
      • (= 1 2) asks the question “are 1 and 2 the same?”
      • (odd? 7) asks the question “is 7 an odd number?”

    • And their return values can be thought of as the answers
      • (= 1 2) returns false
      • (odd? 7) returns true

  • Predicates are an important type of function

16 of 46

User-defined predicates

  • Predicates are just normal functions that happen to return Booleans
  • So you can write your own just like any other kind of function

;; perfect-square?: number -> Boolean

;; True if arg is the square of an

;; integer

> (define perfect-square?

(λ (n)

(integer? (sqrt n))))

> (perfect-square? 4)

#true

> (perfect-square? 3)

#false

17 of 46

Testing equality

As with other languages, Racket has a few different notions of two objects being the same

  • They can be literally the same object in memory
  • They can be different, but equivalent objects

So it has a few different functions for testing equality.

In general DON’T USE THESE ONES

(eq? a b)�The two arguments are literally the same object in memory

    • 4 is not eq? to 4.0
    • Strings may not be eq? to one another

(eqv? a b)�Arguments are the same object or equal numbers.

(equal? a b)�The two arguments are equivalent objects. Works for numbers, strings, and some compound data.

18 of 46

Testing equality

As with other languages, Racket has a few different notions of two objects being the same

  • They can be literally the same object in memory
  • They can be different, but equivalent objects

So it has a few different functions for testing equality.

Instead focus on THESE ONES

(= number1 number2)True when the numbers are the same and throws an exception if they aren’t numbers.

(string=? string1 string2)True when the strings are the same and throws an exception if they aren’t strings

19 of 46

(if time - probs Wednesday next week)

Got a lot of cases?

20 of 46

That's what cond is for!

(if C1 R1 R2) ; if C1 is true, then R1 otherwise R2

(if (> x 5) "big" "small")

(cond [C1 R1] ; if C1 is true, then R1

[C2 R2] ; otherwise if C2 is true, then R2

[Cn Rn]); otherwise if Cn is true, then Rn

(cond [(> x 5) "big"] ; if x > 5, then "big"

[(= x 5) "medium"] ; otherwise if x = 5, "medium"

[else "small"]) ; otherwise "small"

21 of 46

Compound data

22 of 46

Programming as com/position

  • Expression composition
    • Primitive expressions: Constants, variables
    • Compound expressions: Function calls, special forms
  • Function composition
    • Primitive functions:�+,-,*,/, rectangle, overlay, etc.
    • Compound functions:�Created by λ expressions
  • Image composition
    • Primitive images: Rectangles, ellipses
    • Compound images: Overlays, iterated-overlays

23 of 46

Representing a Student in CAESAR

What sort of information do we need to define a "student" in CAESAR?

24 of 46

Representing a Student in CAESAR

3.75

"Connor"

"Bain"

"Computer Science"

"McCormick"

28

gpa

first-name

last-name

major

school

credits

25 of 46

Representing a Student in CAESAR

3.75

"Connor"

"Bain"

"Computer Science"

"McCormick"

28

gpa

first-name

last-name

major

school

credits

first

second

third

fourth

fifth

sixth

26 of 46

Representing a Student in CAESAR

3.75

"Connor"

"Bain"

"Computer Science"

"McCormick"

28

gpa

first-name

last-name

major

school

credits

first

second

third

fourth

fifth

sixth

list structure (numbered)

record structure

(named)

27 of 46

Data Composition

  • Primitive data types
    • Numbers, integers, strings, Booleans
  • Composite data types (structures)
    • List structures: numbered fields
    • Record structures: named fields (the fields available in an object are determined by its type)

28 of 46

Creating and Extract from Composite Data Objects

  • When we have functions that create composite data objects, we call these constructors
  • We'll also have functions that extract the constituent parts of composite data objects, we call these accessors

29 of 46

list (numbered) structures

Aka “structs”

30 of 46

Lists

  • Lists are ordered sequences of data objects
    • Any length
    • Any type of data object
    • Different types can be mixed in the same list
    • Notated as (listof type) in type signatures, where type is the type of data appearing in the list
    • In many procedures the type might just be a variable like T or X, meaning the procedure can handle lists of different kinds of elements
  • Scheme and Racket use a particular kind of list called a linked list
    • We’ll talk more about this in a couple weeks
  • Example: a NetID database
    • A list of string objects

31 of 46

Simple list constructors

(list item1 item2 … itemn)�;; list: T … -> (listof T)

Creates a list containing the specified items, in order

(append list1 list2 … listn)�;; append: (listof T) … -> (listof T)

Creates a new list with all the items from the input lists, in order

32 of 46

Examples

  • Notice that like record structures, lists print as (list data …)
  • The one exception is the empty list (the list with no elements)
    • We’ll explain why later
    • which prints as '()

> (define my-list (list 1 2 3))

(list 1 2 3)

> (append my-list (list 4 5 6))

(list 1 2 3 4 5 6)

> (rest (append my-list

(list 4 5 6)))

(list 2 3 4 5 6)

> (list)

'()

33 of 46

Simple list accessors

(length list)�;; length: (listof T) -> numberReturns the number of items in the list

(list-ref list index)�;; list-ref: (listof T) number -> T

Extracts the element at position index (a number)

    • Index counts from zero
    • So for an 5-element list, the elements are numbered 0, 1, 2, 3, 4

34 of 46

Simple list accessors

(first list), (second list), …, (eighth list)�;; first, etc. : (listof T) -> T��Extracts the specified element of list

(rest list)�;; rest: (listof T) -> (listof T)

Returns all but the first element of list

CORRECTION: This only goes up to eighth!

35 of 46

Lists can…

  • Be empty (no elements)
  • Mix different types of data
  • Have other lists inside them

> (list)

'()

> (length (list))

0

> (list "a" "b" "c" 1 2 3)

(list "a" "b" "c" 1 2 3)

> (list "a" (list "b" "c"))

(list "a" (list "b" "c"))

36 of 46

Examples

  • The length of a list is the number of elements in it
  • When a list has a list within it, the sublist only counts as one element

> (length (list "Lists can have"

(list "other" "lists")

"as elements"))

3

> (length (list "other" "lists"))

2

37 of 46

Examples

  • List items are numbered from zero
    • First item = item 0
    • Second item = item 1
    • Third item = item 2
    • Last item = item (length list)-1
  • Asking for an element past the end of the list gives an IndexOutOfRangeException

> (first (list 1 2 3))

1

> (list-ref (list 1 2 3) 0)

1

> (list-ref (list 1 2 3) 1)

2

> (first (list))

first: expects a non-empty list; given: '()

> (list-ref (list 1 2 3 4) 4)

list-ref: index too large

index: 4

in: (list 1 2 3 4)

38 of 46

Representing a Student in CAESAR

3.75

"Connor"

"Bain"

"Computer Science"

"McCormick"

28

gpa

first-name

last-name

major

school

credits

first (index 0)

second (index 1)

third (index 2)

fourth (index 3)

fifth (index 4)

sixth (index 5)

list structure (numbered)

record structure

(named)

39 of 46

record (named) structures

Aka “structs”

40 of 46

Looking inside record structures

  • Data objects are like forms
    • They have fields
    • Filled in by values
  • The fields
    • Have names (width, height)
    • The fields are filled with other data objects
  • The object’s type (rectangle, ellipse) determines what fields it has

Rectangle

Width: 10

Height: 10

Ellipse

Width: 15

Height: 10

Function

Name: iterated-overlay

Arguments: proc count

Body: [apply group� [up-to count

Color

R: 240

G: 220

B: 0

41 of 46

A new kind of CUSTOM object: the album

  • Let’s say we want to catalog our music collection
  • We’ll use a new kind of data object, the album
  • An album will have three fields, each holding a string:
    • Its title
      • "The Wall","The Fame Monster"
    • The artist who recorded it
      • "Frank Ocean","Frank Sinatra"
    • The album’s genre
      • "rock","hip hop","jazz","classical","comedy"

Note, in Exercise 3 we work with tracks instead of albums

42 of 46

Making new data types

(define-struct typename (field-names))

  • Define-struct is a new kind of special form that makes new data types
  • Defines a set of new functions automagically:
    • (make-typename field-values …)�Makes a new object of the type, given values for its field
    • (typename? object)�Predicate that tests whether object is of the specified type
    • (typename-fieldname object)�Returns the value of the specified field of the object

43 of 46

Example: Making the album type

(define-struct album (title artist genre))

This defines 5 new functions for us automagically:

  • (make-album title artist genre)�;; make-album: string string string -> albumMakes a new album with the specified title, artist, and genre. (constructor)
  • (album? object);; album?: any -> BooleanReturns true if object is an album, otherwise false
  • (album-title album), (album-artist album), (album-genre album)�;; album-title/artist/genre: album -> string Returns the title of the specified album object (accessors)

Note, in Exercise 3 we work with tracks instead of albums

44 of 46

Making an Album object

  • You make an album object by calling its constructor function, make-album
  • Its inputs are
    • The title of the album
    • Its artist
    • Its genre
  • Racket prints the result in the form:�(make-album title artist genre)

> (make-album "Montero"

"Lil Nas X"

"Pop rap")

(make-album "Montero"

"Lil Nas X"

"Pop rap")

Note, in Exercise 3 we work with tracks instead of albums

45 of 46

Accessing album fields

  • You can read the data out of the fields of the object using accessor functions
  • The convention for naming accessor functions is (again): type-field
  • So album-artist is the accessor that gives you the artist field of an album

> (define-struct album

(title artist genre))

> (define my-album

(make-album "Midnights"

"Taylor Swift"

"Synth-pop"))

(make-album "Midnights"

"Taylor Swift"

"Synth-pop"))

> (album-title my-album)

"Midnights"

> (album-artist my-album)

"Taylor Swift"

Note, in Exercise 3 we work with tracks instead of albums

46 of 46

Writing our own Predicates

And we can write functions to work with our albums. For example, a predicate to test if a given album is a Beatles album:

;; Beatles?: album -> Boolean

;; Determines whether an album is by the Beatles

(define Beatles? (lambda (album)

(string=? (album-artist album)

"The Beatles")))

(check-expect (Beatles? (make-album "Title"

"The Beatles"

"Genre"

))

true)

(check-expect (Beatles? (make-album "Title"

"MS MR"

"Genre"))

false)