fixed plai docs
svn: r598
This commit is contained in:
parent
665706fd66
commit
9ef0da0dc6
|
@ -1,6 +1,6 @@
|
|||
|
||||
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:
|
||||
|
||||
|
@ -12,66 +12,95 @@ In the language dialog box, you will find the four _PLAI_ language:
|
|||
This language sequence follows the same progression as the book "How
|
||||
to Design Programs" (htdp). If you are learning Scheme with the book
|
||||
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
|
||||
know so far, and are tailored to address the common errors done at that
|
||||
level.
|
||||
|
||||
The PLAI languages provide constructs that are essential to the
|
||||
coding style prescribed in the class:
|
||||
--- Syntactic forms ---------------------------------------------------
|
||||
|
||||
- Lists are only for holding multiple elements of the same type. Use
|
||||
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) ...) ...)
|
||||
> (define-type ID (VARIANT-ID (FIELD-ID CONTRACT-EXPR) ...) ...)
|
||||
|
||||
Defines the datatype ID and a function ID? that returns true for
|
||||
instances of the datatype, and false for any other value. Here, the
|
||||
name ID? means the given name ID, with an added question mark.
|
||||
|
||||
For each VARIANT-ID, a constructor VARIANT-ID is defined. The
|
||||
constructor takes as many arguments as the variant's FIELD-ID's, and
|
||||
returns and instance of this datatype. Each argument to the
|
||||
constructor is checked by applying the function produced by the
|
||||
variant's PREDICATE-EXPR. DEFINE-TYPE can also use contracts as
|
||||
defined in (lib "contract.ss"), instead of predicates.
|
||||
constructor takes as many arguments as the variant's FIELD-IDs, and
|
||||
it returns an instance of this datatype. Each argument to the
|
||||
constructor is checked by applying the contract produced by the
|
||||
variant's CONTRACT-EXPR.
|
||||
|
||||
The instance constructed by the VARIANT-ID can be deconstructed
|
||||
using TYPE-CASE. Also, for each VARIANT-ID, DEFINE-TYPE also provide
|
||||
functions that accesses the individual fields, and a predicate
|
||||
VARIANT-ID? which recognizes instances of that particular variant.
|
||||
|
||||
In the PLAI Beginner language, a CONTRACT-EXPR should be the name of
|
||||
a predicate, i.e., a procedure of one argument that returns a
|
||||
boolean. In higher language levels, a CONTRACT-EXPR can produce
|
||||
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.
|
||||
|
||||
> (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 ...))
|
||||
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.
|
||||
|
||||
Branches on the datatype instance produced by EXPR, which must be
|
||||
an instance of the specified DATATYPE-ID (previously defined with
|
||||
DEFINE-DATATYPE). Each clause pattern automatically extract the
|
||||
values stored in the fields of the structure. It binds the extracted
|
||||
values them to the names FIELD-IDs in the order that the
|
||||
fields were declared in the corresponding definition in the
|
||||
define-datatype.
|
||||
> (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 will complains if you do not handle all the variants in a
|
||||
datatype. You can use the ELSE keyword as the last clause of a CASES
|
||||
to create a catch-all clause. In that case, variants which are not
|
||||
handled by the other clauses will trigger the evaluation of the
|
||||
ELSE-EXPR.
|
||||
Branches on the datatype instance produced by EXPR, which must be an
|
||||
instance of the specified DATATYPE-ID (previously defined with
|
||||
`define-type'). Each clause pattern automatically extract the values
|
||||
stored in the fields of the structure. It binds the extracted values
|
||||
them to the names FIELD-IDs in the order that the fields were
|
||||
declared in the corresponding definition in the `define-type'.
|
||||
|
||||
If it should not be possible to reach the else clause according to
|
||||
The `type-case' form complains if you do not handle all the variants
|
||||
in a datatype. You can use the `else' keyword as the last clause of
|
||||
a `type-case' to create a catch-all clause. In that case, variants
|
||||
which are not handled by the other clauses will trigger the
|
||||
evaluation of the ELSE-EXPR.
|
||||
|
||||
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
|
||||
ERROR, which will raise an exception. For example:
|
||||
`error', which will raise an exception. For example:
|
||||
|
||||
(cases shape a-circle
|
||||
[circle (c r) (* pi (sqr r))]
|
||||
[else (error "expected a circle!")])
|
||||
(type-case shape a-circle
|
||||
[circle (c r) (* pi (sqr r))]
|
||||
[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)
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user