New-Style Data Definitions In the new style, a Data Definition is a link between a piece of information (something in the real world), and a piece of data (something in the computer). To emphasize this, we add the words "is represented as" in every data definition. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DATA DEFINITIONS FOR SCALAR DATA ;; A FarenTemp is represented as a Real ;; Interp: r represents the temperature r degrees Farenheit ;; A CelsiusTemp is represented as a Real ;; Interp: r represents the temperature r degrees Celsius ;; f2c: FarenTemp -> CelsiusTemp ;; GIVEN: a temperature in Fahrenheit, ;; RETURNS: the equivalent temperature in Celsius. ;; EXAMPLES: ;; (f2c 32) = 0 ;; (f2c 212) = 100 ;; DESIGN STRATEGY: Transcribe Formula ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DATA DEFINITIONS FOR COMPOUND DATA For structs, we put the field names in the representation and the types in the interpretations. We prefer that the types of the fields be given in terms of the information they represent, rather than in terms of how that information is represented. However, this is a flexible criterion. In the examples below, sections labeled "NOTE" are intended as commentary, and not as something a student would be asked to write. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; REPRESENTATION: ;; A CoffeeOrder is represented as (coffee-order size type milk?) ;; with the following fields: ;; INTERP: ;; size : Size is the size of cup desired ;; type : CoffeeType is the kind of coffee order ;; milk : MilkType is the kind of milk ordered (define-struct coffee-order (size type milk)) NOTE: Here (coffee-order ...) in the first line is NOT a constructor. It is a picture of the data as it might be printed out. NOTE: As per Will's advice, we'll have constructor and observer templates as deliverables, but we can drop them later on when everybody gets it. ;; CONSTRUCTOR TEMPLATE ;; (make-coffee-order Size CoffeeType MilkType) ;; OBSERVER TEMPLATE ;; coffee-order-fn : CoffeeOrder -> ?? #; (define (coffee-order-fn co) (... (coffee-order-size co) (coffee-order-type co) (coffee-order-milk co))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; A Size is represented as one of the following integers: ;; -- 8, 12, 16, 20, 30 ;; INTERP: the size of the cup, in fluid ounces NOTE: Constructor template is not necessary for itemization data ;; OBSERVER TEMPLATE: ;; size-fn : Size -> ? #; (define (size-fn s) (cond [(= s 8) ...] [(= s 12) ...] [(= s 16) ...] [(= s 20) ...] [(= s 30) ...])) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; A CoffeeType is represented as a string (any string will do) NOTE: Any time you write String, you MUST write "any string will do". This should eliminate definitions of the form "A Direction is a String". Possible similarly for Number (?). NOTE: In a more detailed representation, we might specify this further. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; A MilkType is one of ;; -- "black" ;; -- "skim" ;; -- "whole" ;; -- "soy" ;; CONSTRUCTOR TEMPLATE: Not needed for an itemization type in Racket ;; note: this may be needed Java or C. ;; OBSERVER TEMPLATE: ;; milk-fn : MilkType -> ? #; (define (milk-fn m) (cond [(string=? m "black") ...] [(string=? m "skim") ...] [(string=? m "whole") ...] [(string=? m "soy") ...])) NOTE: we don't need interpretations for CoffeeType or MilkType because we believe the reader can figure this out. If we were doing this in some other language, or if we believe the reader would not understand these terms well enough to write the code, then we would have to have a more elaborate interpretation. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; A WineOrder is represented as (wine-order vineyard vintage) ;; with the following fields: ;; INTERP: ;; vineyard : Vineyard the origin of the grapes ;; vintage : Vintage the vintage of the grapes ;; A Vineyard is represented as a String (any string will do) ;; A Vintage is represented as a positive integer in [1800,2100] NOTE: it would be OK to write either or both of the following: ;; vineyard : the origin of the grapes, represented as a string (any ;; string will do) ;; vintage : PosInt[1800,2100] the vintage of the grapes (define-struct wine-order (vineyard vintage)) ;; CONSTRUCTOR TEMPLATE: (make-wine-order Vineyard Vintage) ;; OBSERVER TEMPLATE: ;; wine-order-fn : WineOrder -> ?? #; (define (wine-order-fn wo) (... (wine-order-vineyard wo) (wine-order-vintage wo))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; A TeaOrder is represented as (tea-order size type) ;; INTERP: ;; size : Size the size of cup desired ;; type : TeaType the type of tea to be used (define-struct tea-order (size type)) ;; A TeaType is represented as a String (any string will do) ;; NOTE: similarly, it would be OK to write ;; type : String the type of tea to be used, represented as a string ;; (any string will do) ;; It would NOT be OK to write ;; size : NonNegInt the size of the cup desired, in fluid ounces ;; because the size is supposed to be one of the 5 possibilities ;; above. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; In the new scheme, we no longer have mixed data as a category of data. Instead, we will allow an itemization where the alternatives are non-scalars: ;; A BarOrder is one of ;; -- a CoffeeOrder ;; -- a WineOrder ;; -- a TeaOrder ;; bo-fn : BarOrder -> ?? ;; STRATEGY: Cases on order : BarOrder (define (bo-fn order) (cond [(coffee-order? order) ...] [(wine-order? order) ...] [(tea-order? order) ...])) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DATA DEFINITIONS FOR LIST DATA We will treat ListOf<..> as a primitive "representation constructor" ;; An Inventory is represented as a list of BookStatus, in increasing ;; ISBN order, with at most one entry per ISBN. Note that here we've put the constraints on order and multiplicity right in the data definition. ;; CONSTRUCTOR TEMPLATES ;; empty ;; (cons bs inv) -- WHERE bs is a BookStatus inv is an Inventory and (bookstatus-isbn bs) is less than the ISBN of any book in inv. ;; OBSERVER TEMPLATE: ;; inv-fn : Inventory -> ?? #; (define (inv-fn inv) (cond [(empty? inv) ...] [else (... (first inv) (inv-fn (rest inv)))])) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;