4 minute read

Cond operator

(define (aspect-ratio img)
  (cond [Q A]
        [Q A]
        [Q A]))

;[1]
(define (aspect-ratio img)
  (cond [(> (image-height img) (image-width img)) "tall"]
        [(< (image-height img) (image-width img)) "wide"]
        [else "square"]))

;[2]
(define (aspect-ratio img)  
  (if (> (image-height img) (image-width img))
      "tall"
      (if (= (image-height img) (image-width img))
          "square"
          "wide")))

When we have more than 2 cases, then we can use the ‘Cond’ operator. The first one is a simplified version of the cond operator. Observing the simple one makes sense to the real example. [1] and [2] are the same function but with the cond operator and if statement respectively. In the cond expression, each question must produce boolean value.

Data definition

Data definition describes:

  • how to form data of a new type
  • how to represent information as data
  • how to interpret data as information
  • template for operating on data

Data definition simplifies function:

  • restricts data consumed
  • restricts data produced
  • helps generate examples
  • provides template

How to data design recipe

In this example, we will take steps to build city name data. Since it is a name, we are going to use string data.

Structure definition

; INFORMATION       DATA
; Vancouver         "Vancouver"
; Boston            "Boston"

Type comment

;; CityName is String

Interpretation

;; interp. the name of a city

Examples of the data

(define CN1 "Boston")
(define CN2 "Vancouver")

Templates for a 1 argument function

(define (fn-for-city-name cn)
    (... cn)))

Completed design data

;; CityName is String
;; interp. the name of a city

(define CN1 "Boston")
(define CN2 "Vancouver")

#;
(define (fn-for-city-name cn)
    (... cn)))

;; Template rules used:
;; - atomic non-distinct: Image

Combine design function and data

In the previous post, we take a look at how to design a function. Since we work closely with data and function, we need to understand how to do both in terms of using the design recipe. When we want to build a function that consumes non-primitive data, we can copy the template we’ve written in the design recipe.

Besides, all the time designing a function and data is independent. It doesn’t produce a side-effect when we change input or output forms of data consumed by a function.

Intervals

Interval represents a sequence of integers in a row. In the notation, the square bracket means including and round bracket means excluding. Let’s make an example of intervals.

[2, 4]
; 2, 3, 4
(1, 3]
; 2, 3
(3, 6)
; 4, 5

Here is the design example of the interval about row seat number from 1 to 32.

;; SeatNumber is Natural [1, 32]
;; interp. the number of seats in the theater
(define S1 1)   ; start
(define S2 10)  ; middle
(define S3 32)  ; end

#;
(define (fn-for-seatnumber sn)
  (... sn))

;; Template rules used:
;; - atomic non-distinct: Natural [1, 32]

Enumeration

Here is the full design recipe to use enumeration and it represents letter grade.

;; Grade is one of:
;;  - "A"
;;  - "B"
;;  - "C"
;; interp. the grade of a score

;; <examples are redundant for enumerations>
 
#;
(define (fn-for-grade s)
  (cond [(string=? "A" s) (...)]
        [(string=? "B" s) (...)]
        [(string=? "C" s) (...)]))
;; Template rules used:
;;  - one of: 3 cases
;;  - atomic distinct: "A"
;;  - atomic distinct: "B"
;;  - atomic distinct: "C"

Itemization

When we have different subclass types, then we can use the itemization instead of the enumeration. That’s the one difference between the enumeration and itemization.

;; Countdown is one of:
;;  - false
;;  - Natural[1,10]
;;  - "complete"
;; interp.
;;    false means countdown has not yet started
;;    Natural[1,10] means countdown is running and how many seconds left
;;    "complete" means countdown is over

(define CD1 false)
(define CD2 10)
(define CD3 1)
(define CD4 "complete")

(define (fn-for-countdown c)
  (cond [(false? c) (...)]
        [(and (number? c) (<= 1 c) (<= c 10)) (... c)]
        [else (...)]))

;; Template rules used:
;;  - one of: 3 cases
;;  - atomic distinct: false
;;  - atomic non-distinct: Natural[1, 10]
;;  - atomic distinct: "complete"

For the itemization, we can use 2 simplifying rules.

  1. If a given subclass is the last subclass of its type, we can reduce the test to just the guard.
  2. If all remaining subclasses are of the same type, then we can eliminate all of the guards.

Here is the guard to check type of data.

(define (fn-for-tlight tl)
    (cond   [(false? tl) (...)]
            [(and (string? tl) (string=? "red")) (...)]   ; guard
    ))

When we apply those rules, we can reduce this simple version of the template.

(define (fn-for-tlight tl)
    (cond   [(false? tl) (...)]
            [(string=? "red") (...)]   ; guard
    ))

Tips

  • ’#;’: This will comment out following open bracket and close bracket. So in the following example, the right next define statement will be commented out because of ‘#;’.
    #;
    (define (aspect-ratio img)  
    (if (> (image-height img) (image-width img))
        "tall"
        (if (= (image-height img) (image-width img))
            "square"
            "wide")))
    
  • Design is about starting with poorly formed problems and ending up with well-structure solutions

  • information -> data -> template -> function tests

Leave a comment