Google

link="#009900" vlink="#007700" alink="#cc0000"> Teachpacks for How to Design Programs

Simplified Scheme Web Servlets


servlet2.ss

This teachpack provides a simplified API for PLT Scheme servlets. The teachpack does not require any understanding of HTML and higher-order functions. It uses structures and lists, and is therefore well-suited for use with an HtDP course.


Interface

   ; Data Constructors  -------------------------------------------------------
   make-password ; asking for a password
   make-number   ; asking for a number 
   make-yes-no   ; asking for a Yes-No style answer
   make-boolean  ; asking for a true-false style answer
   make-radio    ; requesting one choice from some mutually exclusive choices 
   
   #| Data Definitions --------------------------------------------------------

   Forms ----------------------------------------------------------------------
   Query    = (union String
		(make-password String)
		(make-number   String)
		(make-boolean  String)
		(make-yes-no   String String String)
		(make-radio    String (cons String (listof String)))) 
   FormItem = (list Symbol Query)
   Form     = (cons FormItem (listof FormItem))

   Table -------------------------------------------------------------------
   Response = (union String Number Boolean)
   Table    = (listof (list Symbol Response))
   |#
  
   ; Functions ---------------------------------------------------------------- 

   form?               ; TST -> Boolean 
   ; checking the structure of forms

   form-element?       ; TST -> Boolean 
   ; checking the structure of form-elements

   single-query        ; Query -> Response
   ; posing a single question 

   queries             ; (listof Query) -> (listof Response)
   ; posing a list of questions 

   echo-answers        ; (listof Response) -> true
   ; echoing the answers from a list of questions to a Web page (development)

   form-query          ; Form -> Table
   ; posing a list of questions with tag 

   extract/single      ; Symbol Table -> Response
   ; extracting the answer for a given tag from a response; the tag must
   ; occur exactly once. 

   extract             ; Symbol Table -> (listof Response)
   ; extracting all the answers for a given tag from a response; the list
   ; is empty if there is no such tag. 

   echo-response       ; Table -> true
   ; echoing the response from a form to a Web page (development)
   
   inform              ; String String *-> true 
   ; posting some information on a Web page, wait for continue signal

   final-page          ; String String *-> true
   ; posting some information on a Web page, 
   ; killing the script and all associated backtrack/clone points 


Pragmatics

The following table specifies what kind of answer each form of query produces:

  Query                                      GUI Item         Response
________________________________________________________________________________
  String				     text field       String 
  (make-password String)                     password field   String 
  (make-number   String)                     text field       Number
  (make-boolean  String)                     check box        Boolean 
  (make-yes-no   String String1 String2)     2-pronged radio  String1 or String2
  (make-radio    String loString)            radio button     one of loString
  (make-button   String0)                    submit button    String0

The functions play the following role:

  • form? and form-element? enable programmers to check the well-formedness of their queries.
  • single-query poses a question and waits for a answer from the consumer.
  • queries poses a list of questions and waits for the submission of answers; it produces a list of answers that is as long as the list of given questions.
  • echo-answers echoes a list of answers to a Web page; this function is useful for testing Web form designs.
  • form-query poses a form with queries and waits for the submission of answers; it produces a list of tagged or labeled answers that is as long as the list of given questions.
  • echo-response echoes a response to a Web page as a table.
  • inform posts some information on a Web page and wait for a continue signal (a link) from the consumer; the first string plays the role of a title and the rest form a paragraph.
  • final-page posts some information on a Web page and shuts down the script and all associated backtrack/clone points.

Example

The following example illustrates how the library enables programs to interact with the consumer. In particular, note the properly recursive calls to login in inform-error. Also note how the primitives make-password and make-number deliver strings and numbers, respectively.

#| Login Site -----------------------------------------------------------------
   Author: Matthias Felleisen
   Language: Intermediate 
   Teachpack: servlet2.ss 

   Login Web Site: 
   
   A login site consists of three pages: 
    1. login: request user information: name, password, year-of-birth
       - if correct, respond with greeting for name
       - if incorrect, go to error page 
    2. error: inform user of error, continue goes back to login page
    3. greetings: say hello to name
   The second and third are generated from user input, the first is 
   generated by the program alone. 
   
|# 

;; Login Page -----------------------------------------------------------------

; ask three questions: one plain, one password, one numeric 
(define login-page
  (list 
   (list 'name "User Name")
   (list 'pass (make-password "Password"))
   (list 'yofb (make-number "Year-of-birth"))))

; Table -> true
; process the response for login-page
(define (login r)
  (let ([name (extract/single 'name r)])
    (if (string=? (lookup-password name) (extract/single 'pass r))
        (if (= (lookup-yofb name) (extract/single 'yofb r))
            (greetings name)
            (inform-error "bad data"))
        (inform-error "bad match"))))

; String -> (union false String)
; lookup the password for name in DB
(define (lookup-password name)
  (local ([define (x=? x) (string=? name x)]
          [define r (assf x=? DB)])
    (if (boolean? r) false (second r))))

; String -> (union false Number)
; lookup the year-of-birth for name in DB
(define (lookup-yofb name)
  (local ([define (x=? x) (string=? name x)]
          [define r (assf x=? DB)])
    (if (boolean? r) false (third r))))

(define DB 
  '(("matthias" "okay" 1958)))

;; Error Page -----------------------------------------------------------------

; String -> true
; consume error message, print and enable return to login page 
(define (inform-error s)
  (let ([_ (inform "Error" s)])
    (login (form-query login-page))))

;; Greetings Page -------------------------------------------------------------

; String -> true 
; consume name and display good bye message 
(define (greetings name)
  (inform "Welcome" "Welcome " name " and good bye."))

;; RUN ------------------------------------------------------------------------
(login (form-query login-page))