;POLITICIAN.SCM                6.844              March 4, 2003

;First illustration the object constructor concept: the class of
;State-machines with object constructor MAKE-STATE-MACHINE:

(define (make-state-machine state next-state-proc output-proc)
  (lambda (input)
    (let ((output (output-proc input state)))
      (begin
        (set! state (next-state-proc input state)) output)))) 

#|
The set inputs will be represented as a MEMBERSHIP PREDICATE.  The value
of the combination (REMEMBER INPUT INPUT-HISTORY-PRED) will be a predicate
which is the same as INPUT-HISTORY-PRED except the predicate will also
return #t when its argument has the same value as INPUT:
|#

(define (remember input input-history-pred)
  (lambda (future-input)
    (or (eq? future-input input)
        (input-history-pred future-input))))

;the POLITICIAN object simply remembers whom he met already:

(define politician
  (make-state-machine
   (lambda (input) #f) ;initially return #f for any input
   remember            ;update input-history-pred to "remember" the current input
   (lambda (voter input-history-pred)	
     (if (input-history-pred voter)
         (list 'nice 'ta 'see 'ya 'again voter)
         (list 'pleased 'ta 'meet 'ya voter)))))
#|
(politician 'tom)
(politician 'tom)

(PRINT-STEPS-TO-FILE! "politician-display.txt")
(PRINT-STEPS-TO-FILE! #f)

(HIDE-ALL-STEPS! #t)
(HIDE-ALL-STEPS! #f)

(map politician '(dick tom harry dick))
|#
