;===== ; CS 111 - Week 6 Lecture 1 - 2025-09-30 (require 2htdp/image) (require 2htdp/universe) ;===== ; DATA DEFINITION ; an Anything is an expression of any type ;===== ; DATA DEFINITION ; a list is one of: ; * empty ; * (cons Anything list) ; cons for CONStruct a list ;===== ; signature: cons: Anything list -> list ; purpose: expects any expression and a list, ; and returns a new list with that expression's value ; as its first element, and everything else in the given ; list as the rest of the list ;===== ; DATA DEFINITION ; a NonEmptyList is one of: ; * (cons Anything empty) ; * (cons Anything NonEmptyList) ;===== ; signature: first: NonEmptyList -> Anything ; purpose: expects a non-empty list, and returns the ; first item in that non-empty list ;===== ; signature: rest: NonEmptyList -> list ; purpose: expects a non-empty list, and returns the list ; containing everything except the first element of the ; given list (get it? it returns the REST of the given list) ;**************************************** ; remember: rest ALWAYS returns a list!! ;***************************************** ;===== ; signature: empty?: Anything -> boolean ; purpose: expects any expression with a value, and returns ; whether it is an empty list ;===== ; signature: list?: Anything -> boolean ; purpose: expects any expression with a value, and returns ; whether it is of data type list ;===== ; signature: length: list -> number ; purpose: expects any list, and returns the number of ; (top-level) elements in that list ; ; NOTE: in the list data definition, empty ends a list -- ; it is used to "mark" the end of a list, if you will; ; the empty ending a list is NOT considered to be an element of ; that list! ;===== ; START of an **INCOMPLETE** template for a function ; "walking through" a list ; ; * see if the list is empty - if so, handle that empty list ; * otherwise, you know to handle a NON-empty list ; ; (cond ; [(empty? my-list) ...] ; [else ...] ; ) ; for helping us COMPLETE this template, ; let's write our OWN version of length, ; say, len ;===== ; signature: len: list -> number ; purpose: expects any list, and returns the number of ; top-level elements in that list (check-expect (len empty) 0) (check-expect (len (list 1 2 3 4 5 6 7 8)) 8) (define (len a-list) (cond [(empty? a-list) 0] ; when a-list is not empty, add 1 (for the 1st element) ; to the length of the *rest* o a-list [else (+ 1 (len (rest a-list)))] ) ) (len (list 1 "moo" #true "red" 21 null pi e)) ;===== ; COMPLETED template for a function that "walks through a list ; ; (define (a-list-funct ... a-list ...) ; (cond ; [(empty? a-list) ...] ; [else (... ; (first a-list) ... ; (a-list-funct ... (rest a-list) ...) ...) ; ] ; ) ; ) ;===== ; fun fact: DrRacket has a module 2htdp/batch-io (require 2htdp/batch-io) ;----- ; 2htdp/batch-io has a selection of file input and file output functions ; (as would be needed for a so-called batch program, one with ; no interactive input/output, ; that reads its needed input from file(s) and writes its ; resulting output to file(s) ;----- ; here is an example of one of its functions that reads from ; a file: ;----- ; signature: read-lines: string -> list ; purpose: expects the name of a file written as a string -- ; either its full/"absolute" name OR its name in the current ; working directory -- ; has the SIDE-EFFECT of trying to open and read the contents of ; that file, ; and returns the contents read as a list of strings, ; each line in the file being one string in the result (read-lines "111lect06-1.rkt") ; so, this essentially counts the number of lines in 111lect06-1.rkt! ; (since read-lines returns a list of strings, ; one string per line in the file, ; and len counts the number of items in the list!) (len (read-lines "111lect06-1.rkt")) ;----- ; signature: read-words: string -> list ; purpose: expects the name of a file written as a string -- ; either its full/"absolute" name OR its name in the current ; working directory -- ; has the SIDE-EFFECT of trying to open and read the contents of ; that file, ; and returns the contents as a list of strings, with each ; white-space-separated "token"/"word" being a string in this list (read-words "111lect06-1.rkt") ; so, the length of the list that read-words returns is longer ; than that returned by read-lines: (len (read-words "111lect06-1.rkt")) ;===== ; len "walks through" a list to compute a number, here the ; number of items in its argument list; ; some functions that "walk through" a list return a new list ;----- ; for example -- what if we would like a function to add 1 to ; each number in a list of numbers? ;===== ; signature: add1-list: list -> list ; purpose: expects a list of numbers, and returns a list of numbers ; in which each number is 1 larger than its counterpart in the ; given list (check-expect (add1-list empty) empty) (check-expect (add1-list (list 10 20 30 40)) (cons 11 (cons 21 (cons 31 (cons 41 empty))))) (define (add1-list num-list) (cond ; there are no numbers in an empty list - so if num-list ; is empty, just return an empty list [(empty? num-list) empty] ; but, if num-list is not empty, create a new list ; from the result of cons-ing 1 + the first element in ; num-list to the result of calling add1-list on the ; rest of num-list [else (cons (add1 (first num-list)) (add1-list (rest num-list))) ] ) ) (add1-list (list 10 20 30 40))