From 9ef0da0dc60e027596f42ac7f899faebc584c831 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 16 Aug 2005 02:11:48 +0000 Subject: [PATCH] fixed plai docs svn: r598 --- collects/plai/doc.txt | 113 ++++++++++++++++++++++++++---------------- 1 file changed, 71 insertions(+), 42 deletions(-) diff --git a/collects/plai/doc.txt b/collects/plai/doc.txt index 4c901032fb..5747f29c7e 100644 --- a/collects/plai/doc.txt +++ b/collects/plai/doc.txt @@ -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)