Recursive Data DefinitionsCS 5010 Program Design Paradigms “Bootcamp”Week 02, Lesson 2TexPoint fonts used in EMF. Read the TexPoint manual before you delete this box.: AAA1
How to represent info of arbitrary size?phone bookpixels in an imagebombs dropped by a UFOslides in a presentationApproach: think about how such information is constructed.
Example: PizzaHow do you construct a pizza? Two possibilities:grab a pizza crusttake a pizza and add a topping...and so on
Data Definition(define-struct topped-pizza (topping base))A Topping is a String.A Pizza is either-- the string "plain crust"-- (make-topped-pizza Topping Pizza)
Examples(define plain-pizza "plain crust")(define cheese-pizza  (make-topped-pizza "cheese" plain-pizza))(define anchovies-cheese  (make-topped-pizza "anchovies" cheese-pizza))(define onions-anchovies-cheese  (make-topped-pizza "onions" anchovies-cheese))
This data definition is self-referential(define-struct topped-pizza (topping base))A Topping is a String.A Pizza is either-- the string "plain crust"-- (make-topped-pizza Topping Pizza)We also call this a recursive data definition
Template for pizza functionspizza-fn : Pizza -> ??Given a Pizza, produce ....(define (pizza-fn pizza)  (cond    [(plain-pizza? pizza) ...]    [else (... (topped-pizza-topping pizza)               (pizza-fn (topped-pizza-base pizza)))]))Add to wishlist:plain-pizza? : Pizza -> Booleanreturns true iff the given pizza is a plain pizza
This template is self-referentialpizza-fn : Pizza -> ??Given a Pizza, produce ....(define (pizza-fn pizza)  (cond    [(plain-pizza? pizza) ...]    [else (... (topped-pizza-topping pizza)               (pizza-fn(topped-pizza-base pizza)))]))We also call this a recursive template
Example: number of toppingsnumber-of-toppings : Pizza -> NumberGiven a Pizza, produce the number of toppingsExamples:(number-of-toppings plain-pizza) = 0(number-of-toppings cheese-pizza) = 1(number-of-toppings anchovies-cheese) = 2(number-of-toppings onions-anchovies-cheese) = 3
Example: number of toppingsnumber-of-toppings : Pizza -> NumberGiven a Pizza, produce the number of toppingsStrategy: structural decomposition(define (number-of-toppings pizza)  (cond    [(plain-pizza? pizza) ...]    [else (... (topped-pizza-topping pizza)               (number-of-toppings(topped-pizza-base pizza)))]))How many toppings does the plain pizza have?Answer: 0
Example: number of toppingsnumber-of-toppings : Pizza -> NumberGiven a Pizza, produce the number of toppingsStrategy: structural decomposition(define (number-of-toppings pizza)  (cond    [(plain-pizza? pizza) 0]    [else (... (topped-pizza-topping pizza)               (number-of-toppings(topped-pizza-base pizza)))]))How many toppings does the plain pizza have?Answer: 0
Example: number of toppingsnumber-of-toppings : Pizza -> NumberGiven a Pizza, produce the number of toppingsStrategy: structural decomposition(define (number-of-toppings pizza)  (cond    [(plain-pizza? pizza) 0]    [else (... (topped-pizza-topping pizza)               (number-of-toppings(topped-pizza-base pizza)))]))Q: If we knew the number of toppings on the pizza base, how many toppings would there on the whole pizza?Answer: one more topping!
Example: number of toppingsnumber-of-toppings : Pizza -> NumberGiven a Pizza, produce the number of toppings(define (number-of-toppings pizza)  (cond    [(plain-pizza? pizza) 0]    [else (+ 1 (number-of-toppings(topped-pizza-base pizza)))]))Self-reference in the data definition leads to self-reference in the template;Self-reference in the template leads to self-reference in the code.Self-reference in the data definition leads to self-reference in the template;Self-reference in the template leads to self-reference in the code.Self-reference in the data definition leads to self-reference in the template;Self-reference in the template leads to self-reference in the code.Self-reference in the data definition leads to self-reference in the template;Self-reference in the template leads to self-reference in the code.
Don't forget the tests!;; plain pizza(check-expect  (number-of-toppings plain-pizza)   0);; one topping(check-expect (number-of-toppings cheese-pizza)  1)...etc...
Steps for the design strategyWhat's the answer for the empty pizza?If you knew the answer for the base pizza, how would you get the answer for the whole pizza?
Many other examplesadd-anchovies : Pizza -> Pizzaremove-all-anchovies : Pizza -> PizzaProduce a Pizza like the given one, but with all anchovies removed.replace-all-anchovies-with-onions : Pizza -> Pizzareplace-all-anchovies : Pizza Topping -> Pizzareplace-topping : Pizza Topping Topping -> PizzaProduce a Pizza like the given one, but with all instances of the first topping replaced by the second one.
Check the wishlistplain-pizza? : Pizza -> Booleanreturns true iff the given pizza is a plain pizza;; examples: ...;; strategy: function composition(define (plain-pizza? pizza)  (and    (string? pizza)    (string=? pizza "plain crust")));; tests: ....
SummaryRepresent arbitrary-sized information using a self-referential (or recursive) data definition.Self-reference in the data definition leads to self-reference in the template.Self-reference in the template leads to self-reference in the code.Follow the recipe!

Week 02 Lesson 02 Recursive Data Definitions

  • 1.
    Recursive Data DefinitionsCS5010 Program Design Paradigms “Bootcamp”Week 02, Lesson 2TexPoint fonts used in EMF. Read the TexPoint manual before you delete this box.: AAA1
  • 2.
    How to representinfo of arbitrary size?phone bookpixels in an imagebombs dropped by a UFOslides in a presentationApproach: think about how such information is constructed.
  • 3.
    Example: PizzaHow doyou construct a pizza? Two possibilities:grab a pizza crusttake a pizza and add a topping...and so on
  • 4.
    Data Definition(define-struct topped-pizza(topping base))A Topping is a String.A Pizza is either-- the string "plain crust"-- (make-topped-pizza Topping Pizza)
  • 5.
    Examples(define plain-pizza "plaincrust")(define cheese-pizza (make-topped-pizza "cheese" plain-pizza))(define anchovies-cheese (make-topped-pizza "anchovies" cheese-pizza))(define onions-anchovies-cheese (make-topped-pizza "onions" anchovies-cheese))
  • 6.
    This data definitionis self-referential(define-struct topped-pizza (topping base))A Topping is a String.A Pizza is either-- the string "plain crust"-- (make-topped-pizza Topping Pizza)We also call this a recursive data definition
  • 7.
    Template for pizzafunctionspizza-fn : Pizza -> ??Given a Pizza, produce ....(define (pizza-fn pizza) (cond [(plain-pizza? pizza) ...] [else (... (topped-pizza-topping pizza) (pizza-fn (topped-pizza-base pizza)))]))Add to wishlist:plain-pizza? : Pizza -> Booleanreturns true iff the given pizza is a plain pizza
  • 8.
    This template isself-referentialpizza-fn : Pizza -> ??Given a Pizza, produce ....(define (pizza-fn pizza) (cond [(plain-pizza? pizza) ...] [else (... (topped-pizza-topping pizza) (pizza-fn(topped-pizza-base pizza)))]))We also call this a recursive template
  • 9.
    Example: number oftoppingsnumber-of-toppings : Pizza -> NumberGiven a Pizza, produce the number of toppingsExamples:(number-of-toppings plain-pizza) = 0(number-of-toppings cheese-pizza) = 1(number-of-toppings anchovies-cheese) = 2(number-of-toppings onions-anchovies-cheese) = 3
  • 10.
    Example: number oftoppingsnumber-of-toppings : Pizza -> NumberGiven a Pizza, produce the number of toppingsStrategy: structural decomposition(define (number-of-toppings pizza) (cond [(plain-pizza? pizza) ...] [else (... (topped-pizza-topping pizza) (number-of-toppings(topped-pizza-base pizza)))]))How many toppings does the plain pizza have?Answer: 0
  • 11.
    Example: number oftoppingsnumber-of-toppings : Pizza -> NumberGiven a Pizza, produce the number of toppingsStrategy: structural decomposition(define (number-of-toppings pizza) (cond [(plain-pizza? pizza) 0] [else (... (topped-pizza-topping pizza) (number-of-toppings(topped-pizza-base pizza)))]))How many toppings does the plain pizza have?Answer: 0
  • 12.
    Example: number oftoppingsnumber-of-toppings : Pizza -> NumberGiven a Pizza, produce the number of toppingsStrategy: structural decomposition(define (number-of-toppings pizza) (cond [(plain-pizza? pizza) 0] [else (... (topped-pizza-topping pizza) (number-of-toppings(topped-pizza-base pizza)))]))Q: If we knew the number of toppings on the pizza base, how many toppings would there on the whole pizza?Answer: one more topping!
  • 13.
    Example: number oftoppingsnumber-of-toppings : Pizza -> NumberGiven a Pizza, produce the number of toppings(define (number-of-toppings pizza) (cond [(plain-pizza? pizza) 0] [else (+ 1 (number-of-toppings(topped-pizza-base pizza)))]))Self-reference in the data definition leads to self-reference in the template;Self-reference in the template leads to self-reference in the code.Self-reference in the data definition leads to self-reference in the template;Self-reference in the template leads to self-reference in the code.Self-reference in the data definition leads to self-reference in the template;Self-reference in the template leads to self-reference in the code.Self-reference in the data definition leads to self-reference in the template;Self-reference in the template leads to self-reference in the code.
  • 14.
    Don't forget thetests!;; plain pizza(check-expect (number-of-toppings plain-pizza) 0);; one topping(check-expect (number-of-toppings cheese-pizza) 1)...etc...
  • 15.
    Steps for thedesign strategyWhat's the answer for the empty pizza?If you knew the answer for the base pizza, how would you get the answer for the whole pizza?
  • 16.
    Many other examplesadd-anchovies: Pizza -> Pizzaremove-all-anchovies : Pizza -> PizzaProduce a Pizza like the given one, but with all anchovies removed.replace-all-anchovies-with-onions : Pizza -> Pizzareplace-all-anchovies : Pizza Topping -> Pizzareplace-topping : Pizza Topping Topping -> PizzaProduce a Pizza like the given one, but with all instances of the first topping replaced by the second one.
  • 17.
    Check the wishlistplain-pizza?: Pizza -> Booleanreturns true iff the given pizza is a plain pizza;; examples: ...;; strategy: function composition(define (plain-pizza? pizza) (and (string? pizza) (string=? pizza "plain crust")));; tests: ....
  • 18.
    SummaryRepresent arbitrary-sized informationusing a self-referential (or recursive) data definition.Self-reference in the data definition leads to self-reference in the template.Self-reference in the template leads to self-reference in the code.Follow the recipe!

Editor's Notes

  • #2 Welcome to Week 2, Lesson 2: Recursive Data DefinitionsWe have learned how to represent atomic data, enumeration data (including interval data), and compound data.But all this data is of fixed size. In this lesson we will begin our discussion of how to represent data of variable and unbounded size.
  • #17 I've written down the purpose statements for two of these functions. Exercise: write down purpose statements for the other three.Another exercise: can you think of other examples of information that might be represented by a self-referential data definition like the one for Pizza?