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))