Chapter 2 - Do It, Do It Again, and Again, and Again…

Chapter 2 - Do It, Do It Again, and Again, and Again…#

1996 Friedman, Daniel P. & Matthias Felleisen. The Little Schemer. 4e. MIT Press.


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Chapter 2 - Do It, Do It Again, and Again, and Again...

; LAT?
;   determines whether a given list does not contain a list
;   inputs: list
;   output: bool
;
; constructing function lat?
;   first  commandment (prelim) - always ask null? as the first question in expressing any function
;   fourth commandment (prelim) - always change at least one argument while recurring; it must be changed to be closer to termination; the changing argument must be tested in the termination condition: when using cdr, test termination with null?.
;   look at each S-expression in a list, in turn, and ask if it is an atom, until it runs out of S-expressions
;   if it runs out of S-expressions without encountering a list, the return value is #t; if it encounters a list, the return value is #f
(define lat?
  (lambda (l)
    (cond                                   ; there are three questions bc a list can be empty, have an atom in the first position, or have a list in the first position
      ( (null? l) #t                   )    ; 1) Is the list empty/null?
      ( (atom? (car l)) (lat? (cdr l)) )    ; 2) Is the current S-expression an atom? If so, then recur on the remainder of the list.
      ( else #f                        )))) ; 3) Otherwise, the list is not a lat.

(lat? '(Jack Sprat could eat no chicken fat))   ; #t -                         each S-expression in the list is an atom
(lat? '((Jack) Sprat could eat no chicken fat)) ; #f - it is not the case that each S-expression in the list is an atom
(lat? '(Jack (Sprat could) eat no chicken fat)) ; #f - it is not the case that each S-expression in the list is an atom
(lat? '())                                      ; #t -                         each S-expression in the list is an atom
(lat? '(bacon and eggs))                        ; #t
  ; null? (bacon and eggs) - no
  ; atom? bacon - yes
  ;   null? (and eggs) - no
  ;   atom? and - yes
  ;     null? (eggs) - no
  ;     atom? eggs - yes
  ;       null? () - yes
  ;       #t
(lat? '(bacon (and eggs)))                      ; #f
  ; null? (bacon (and eggs)) - no
  ; atom? bacon - yes
  ;   null? ((and eggs)) - no
  ;   atom? (and eggs) - no
  ;   #f


; OR
;   inputs: bool, bool
;   output: bool
;
; asks two questions, one at a time
; 1) if the first one is true it stops and answers true
; 2) otherwise it asks the second question and answers with whatever the second question answers
(or (null? '()) (null? '(d e f g)))   ; #t
(or (null? '(a b c)) (null? '()))     ; #t
(or (null? '(a b c)) (null? '(atom))) ; #f


; MEMBER?
;   determines whether a given atom is the same as at least one atom in a lat
;   inputs: atom, lat
;   output: bool
;
; constructing function member?
;   first  commandment (prelim) - always ask null? as the first question in expressing any function
;   first  commandment (final)  - when recurring on a list of atoms, lat, ask two questions about it: (null? lat) and else
;   fourth commandment (prelim) - always change at least one argument while recurring; it must be changed to be closer to termination; the changing argument must be tested in the termination condition: when using cdr, test termination with null?.
;   look at each atom in a lat, in turn, and ask if it is the given atom, until it runs out of atoms
;   if it runs out of atoms without encountering the given atom, the return value is #f; if it encounters the given atom, the return value is #t
(define member?
  (lambda (a lat)
    (cond
      ( (null? lat) #f                         )    ; 1)  Is the list empty/null?
      ( else        (or (eq? (car lat) a)           ; 2a) Is the current atom the same as the given atom?
                        (member? a (cdr lat))) )))) ; 2b) If not, then recur on the remainder of the lat.
; (define member?
;   (lambda (a lat)
;     (cond
;       ( (null? lat)       #f                    )
;       ( (eq? (car lat) a) #t                    )
;       ( else              (member? a (cdr lat)) ))))

(member? 'tea '(coffee tea or milk))                ; #t
(member? 'poached '(fried eggs and scrambled eggs)) ; #f
(member? 'meat '(mashed potatoes and meat gravy))   ; #t
  ; null? (mashed potatoes and meat gravy) - no
  ; eq? mashed meat - no
  ; (or #f null? (potatoes and meat gravy)) - no
  ; (or #f eq? potatoes meat) - no
  ; (or #f (or #f null? (and meat gravy))) - no
  ; (or #f (or #f eq? and meat) - no
  ; (or #f (or #f (or #f null? (meat gravy)))) - no
  ; (or #f (or #f (or #f eq? meat meat))) - yes
  ; (or #f (or #f (or #f #t)))
  ; (or #f (or #f #t))
  ; (or #f #t)
  ; #t
(member? 'liver '(bagels and lox))                  ; #f
  ; null? (bagels and lox)
  ; eq? bagels liver
  ; (or #f null? (and lox))
  ; (or #f eq? and liver)
  ; (or #f (or #f null? (lox)))
  ; (or #f (or #f eq? lox liver))
  ; (or #f (or #f (or #f null? ())))
  ; (or #f (or #f (or #f #f)))
  ; (or #f (or #f #f))
  ; (or #f #f)
  ; #f