fixed plai docs

svn: r598
This commit is contained in:
Matthew Flatt 2005-08-16 02:11:48 +00:00
parent 665706fd66
commit 9ef0da0dc6

View File

@ -1,6 +1,6 @@
The _Programming Languages: Application and Interpretations_ languages The _Programming Languages: Application and Interpretations_ languages
are companion to the textbook, and to the _CS173_ class at Brown university. are companion to the textbook of the same name.
In the language dialog box, you will find the four _PLAI_ language: In the language dialog box, you will find the four _PLAI_ language:
@ -12,67 +12,96 @@ In the language dialog box, you will find the four _PLAI_ language:
This language sequence follows the same progression as the book "How This language sequence follows the same progression as the book "How
to Design Programs" (htdp). If you are learning Scheme with the book to Design Programs" (htdp). If you are learning Scheme with the book
while taking the class, the PLAI languages will provide the same while taking the class, the PLAI languages will provide the same
support as the htdp languages. Namely, at each language level the support as the HtDP languages. Namely, at each language level the
error messages you receive are explained in term of the constructs you error messages you receive are explained in term of the constructs you
know so far, and are tailored to address the common errors done at that know so far, and are tailored to address the common errors done at that
level. level.
The PLAI languages provide constructs that are essential to the --- Syntactic forms ---------------------------------------------------
coding style prescribed in the class:
- Lists are only for holding multiple elements of the same type. Use > (define-type ID (VARIANT-ID (FIELD-ID CONTRACT-EXPR) ...) ...)
DEFINE-TYPE and TYPE-CASE to group elements of different types.
- All functions must have tests that exercise non-trivial cases. Use
TEST, TEST/PRED and TEST/EXN (below) to create a persistent
collection of tests for your code.
> (define-type id (variant-id (field-id predicate-expr) ...) ...)
Defines the datatype ID and a function ID? that returns true for Defines the datatype ID and a function ID? that returns true for
instances of the datatype, and false for any other value. Here, the instances of the datatype, and false for any other value. Here, the
name ID? means the given name ID, with an added question mark. name ID? means the given name ID, with an added question mark.
For each VARIANT-ID, a constructor VARIANT-ID is defined. The For each VARIANT-ID, a constructor VARIANT-ID is defined. The
constructor takes as many arguments as the variant's FIELD-ID's, and constructor takes as many arguments as the variant's FIELD-IDs, and
returns and instance of this datatype. Each argument to the it returns an instance of this datatype. Each argument to the
constructor is checked by applying the function produced by the constructor is checked by applying the contract produced by the
variant's PREDICATE-EXPR. DEFINE-TYPE can also use contracts as variant's CONTRACT-EXPR.
defined in (lib "contract.ss"), instead of predicates.
The instance constructed by the VARIANT-ID can be deconstructed In the PLAI Beginner language, a CONTRACT-EXPR should be the name of
using TYPE-CASE. Also, for each VARIANT-ID, DEFINE-TYPE also provide a predicate, i.e., a procedure of one argument that returns a
functions that accesses the individual fields, and a predicate boolean. In higher language levels, a CONTRACT-EXPR can produce
VARIANT-ID? which recognizes instances of that particular variant. anything that is allowed as a contract by MzLib's "contract.ss"
library (which includes predicate procedures).
An instance constructed by the VARIANT-ID can be deconstructed using
`type-case'. Also, for each FIELD-ID of a VARIANT-ID, `define-type'
provides VARIANT-ID-FIELD-ID to access each field in an instance of
each variant, and a predicate VARIANT-ID? to recognize instances of
the variant.
In PLAI Intermediate and later, `define-type' produces additional
contract-related bindings, and it also supports a generalization of
ID. See "Datatypes and Contracts" below.
> (type-case datatype-id expr (variant-id (field-id ...) result-expr ...) ...) > (type-case DATATYPE-ID EXPR (VARIANT-ID (FIELD-ID ...) RESULT-EXPR ...) ...)
> (type-case datatype-id expr (variant-id (field-id ...) result-expr ...) ... (else else-expr ...)) > (type-case DATATYPE-ID EXPR (VARIANT-ID (FIELD-ID ...) RESULT-EXPR ...) ...
(else ELSE-EXPR ...))
Branches on the datatype instance produced by EXPR, which must be Branches on the datatype instance produced by EXPR, which must be an
an instance of the specified DATATYPE-ID (previously defined with instance of the specified DATATYPE-ID (previously defined with
DEFINE-DATATYPE). Each clause pattern automatically extract the `define-type'). Each clause pattern automatically extract the values
values stored in the fields of the structure. It binds the extracted stored in the fields of the structure. It binds the extracted values
values them to the names FIELD-IDs in the order that the them to the names FIELD-IDs in the order that the fields were
fields were declared in the corresponding definition in the declared in the corresponding definition in the `define-type'.
define-datatype.
TYPE-CASE will complains if you do not handle all the variants in a The `type-case' form complains if you do not handle all the variants
datatype. You can use the ELSE keyword as the last clause of a CASES in a datatype. You can use the `else' keyword as the last clause of
to create a catch-all clause. In that case, variants which are not a `type-case' to create a catch-all clause. In that case, variants
handled by the other clauses will trigger the evaluation of the which are not handled by the other clauses will trigger the
ELSE-EXPR. evaluation of the ELSE-EXPR.
If it should not be possible to reach the else clause according to If it should not be possible to reach the `else' clause according to
the logic of your program, your ELSE-EXPR should be a call to the logic of your program, your ELSE-EXPR should be a call to
ERROR, which will raise an exception. For example: `error', which will raise an exception. For example:
(cases shape a-circle (type-case shape a-circle
[circle (c r) (* pi (sqr r))] [circle (c r) (* pi (sqr r))]
[else (error "expected a circle!")]) [else (error "expected a circle!")])
--- Datatypes and Contracts ------------------------------------------------
> (define-type (ID PARAM-ID ...) (VARIANT-ID (FIELD-ID CONTRACT-EXPR) ...) ...)
This form of `define-type' is supported only in the PLAI
Intermediate langauge and higher.
Each PARAM-ID stands for a contract parameter, and can
appear as a free variable in the CONTRACT-EXPRs. When VARIANT-ID is
used directly, then `any/c' is substituted for each PARAM-ID to
obtain the relevant field contracts. Using ID by itself after
`define-type' is the same as (ID) with no PARAM-IDs.
VARIANT-ID-of is bound to a constructor generator for each
VARIANT-ID. Given a contract for each PARAM-ID, it produces a
constructor whose field contracts are the CONTRACT-EXPRs with
PARAM-IDs replaced by the given contracts.
ID-of/c is bound to a contract generator. Given a contract for each
PARAM-ID, it produces a contract that corresponds to the union of
the variant contracts PARAM-IDs replaced by the given contracts in
the CONTRACT-EXPRs.
Finally, VARIANT-ID-of/c is bound to a contract generator for each
VARIANT-ID. Given a contract for each PARAM-ID, it produces a
constructor whose field contracts are the CONTRACT-EXPRs with
PARAM-IDs replaced by the given contracts.
--- Testing support ---------------------------------------------------
> (test result expected-value) > (test result expected-value)
Compares the result of a test expression to the expected value, and Compares the result of a test expression to the expected value, and