Please send questions to st10@humboldt.edu .

; CS 131 - Week 4, Lecture 1
; 09-14-10

;----------
; enumerations...
; ...for those situations where you have
;    a relatively small, discrete number of specific
;    cases

; examples: the keystroke's for Week 3 Lab's world
;    were just "u" and "d";
; *   a multiple choice question's answers might be
;     1, 2, 3, or 4
; etc.

; really, such an enumeration is just a very simple,
;    restricted type of data --
; we could consider that a simple data type;

; FOR NOW, we'll "define" such a data type with
;   a comment (the comment, in this case, is our
;   DATA DEFINITION for such a data type):

;----------
; a WorldAction is a string equal to "u" or "d"

;----------
; a TrafficLightColor is a string of "yellow", "red", or "green"

;----------
; a StudentAnswer is 1, 2, 3, or 4

; once you have written a DATA DEFINITION such as the above,
;    you can now USE that in function signatures within
;    that Definitions window

;----------
; signature: affect-world: number WorldAction -> number

;----------
; signature: traffic-light-next: TrafficLightColor 
;               -> TrafficLightColor

;----------
; COURSE STYLE STANDARD -
; when you HAVE an enumeration, give a data definition
;    comment for that,
; and then use that new type name as appropriate in 
;    function signatures...

; programming with enumerations is pretty straightforward --
;   often, you can have a cond expression case for
;   each of the enumeration's options...

;----------
; signature: traffic-light-next: TrafficLightColor 
;               -> TrafficLightColor

; purpose: expects a traffic light's color, and produces
;    the next color that traffic light should have:
;    after it's green, it should turn yellow;
;    after it's yellow, it should turn red;
;    after it's red, it should turn green

(define (traffic-light-next curr-color)
  (cond
    [(string=? curr-color "red") "green"]
    [(string=? curr-color "green") "yellow"]
    [(string=? curr-color "yellow") "red"]
  )
)

(check-expect (traffic-light-next "red") "green")
(check-expect (traffic-light-next "green") "yellow")
(check-expect (traffic-light-next "yellow") "red")
(traffic-light-next "red")

; uncomment this to see the error you get if you
;    call this function with a non-traffic-light-color
;(traffic-light-next "purple")

;----------
; Itemizations

; an itemization generalizes intervals and enumerations;
;    a kind of data that COMBINES existing data classes
;    with individual pieces of data

; consider the string->number function;
(string->number "13.5")   ; produces 13.5
(string->number "george") ; produces false

;...how can you write THAT function's signature?

; define an itemization data type first:

;----------
; a NumOrF is one of:
;    - false
;    - a number


;----------
; signature: string->number: string -> NumOrF

; when an itemization is expected by a function,
;    a cond expression will often be involved in
;    handling that data,
;    often with one case per kind of data;

; consider the odd little function add3,
;    which expects a NumOrF and produces 3 plus
;    that value (treating false as a 0)

;----------
; signature: add3: NumOrF -> number
; purpose: expects a NumOrF and produces 3 plus
;    that value (treating false as a 0)

; note: number? is a predicate -- a boolean function --
;    that expects any expression, and produces whether
;    that expression has type number

; note: equal? can compare any two expressions (even if
;     they're of different types, but produces whether
;     they are of the same type and value

(define (add3 a-num-or-f) ; a-NumOrF or aNumOrF also OK, etc.
  (cond
    [(number? a-num-or-f) (+ a-num-or-f 3)]
    [(equal? a-num-or-f false) 3]
    ;[else 3] ; commented this out so I'll get an error
              ; if this is called with non-NumOrF data
  )
)

(check-expect (add3 false) 3)
(check-expect (add3 5) 8)
(add3 false)
(add3 5)

;----------
; now: WOULDN'T IT BE NICE
; ...to be able to gather info about a single "thing"
;    together?

; I can do that in Racket with a structure (a struct)
; ...ONE kind of user-defined custom type;

; first principle of abstraction and locality:
; put things together that should go together!

; you use the operation define-struct to define a new struct;

; it expects the name of the desired new struct type,
;    and then, in parentheses, the list of characteristics
;    for that new struct

(define-struct Bird (image speed direction x y))
(define-struct Point (x y))
(define-struct Student (last-name first-name id email))

; this ONE line gives me several new operations:
;    a way to construct new instances of my new type,
;    called a constructor:   make-<structname>
;    call it with the values for each characteristic
;       to get an instance with those characteristics

(make-Point 3 4)
(make-Student "Brown" "Charlie" 1313 "snoopyfan@petaluma.com")

; here is a type position:

(define-struct position (x y))

;----------
; NEXT STEPS, to be discussed THURSDAY...
; *   define-struct also gives you SELECTOR (sometimes also 
;     called ACCESSOR) functions, that allow you to grab the
;     value of a particular characteristic of a struct;
;     *   there is one for each characteristic, named
;         <struct-name>-<charact-name>
;     *   so, for the position struct above,
;         position-x: expects a position and produces its x value
;         position-y: expects a position and produces its y value

(position-x (make-position 3 4))  ; produces 3
(position-y (make-position 3 4))  ; produces 4

; *   how would the user know the desired TYPES and MEANINGS
;     of each of a struct's characteristic? We need to 
;     accompany each define-struct with a comment making that
;     information clear; we'll discuss this on Thursday, too.
;
; *   and, define-struct gives you a predicate function, too,
;     (a boolean function) that expects any expression and
;     produces true if it is an instance of that struct;
;     its name: <struct-name>?
;     *   so for struct position, this predicate is position?
;         for Bird, this predicate function is Bird?
;         etc.

; this produces true:

(position? (make-position 3 4))

; this produces false:

(position? (make-Student "Brown" "Charlie" 1313 
                         "snoopyfan@petaluma.com"))