Merged htdp-lib.scblr and teachpacks/error-composition.scrbl into htdp/htdp.scrbl,
to form a single manual titled "Implementing HtDP Teachpacks, Libraries, and Customized Teaching Languages"
This commit is contained in:
parent
91d5c92415
commit
2c075978fd
|
@ -1,75 +1,47 @@
|
|||
#lang scribble/doc
|
||||
|
||||
@(require scribble/manual (for-label scheme))
|
||||
@(require scribble/manual
|
||||
(for-label [except-in racket require]
|
||||
[only-in lang/htdp-beginner require]))
|
||||
|
||||
@title[#:style '(toc) #:tag "htdp"]{How to Design HtDP TeachPacks}
|
||||
@title[#:style 'toc #:tag "htdp"]{Implementing HtDP Teachpacks, Libraries, and Customized Teaching Languages}
|
||||
|
||||
@section{What are TeachPacks}
|
||||
DrRacket has two different mechanisms for making available additional functions
|
||||
and functionality to students using the teaching languages.
|
||||
|
||||
TeachPacks for "How to Design Programs" provide functionality that extends
|
||||
the teaching languages for specific exercises. The extensions fit smoothly
|
||||
to the teaching languages so that students don't get nonsensical error
|
||||
messages or undocumented language features through the backdoor.
|
||||
|
||||
@; -----------------------------------------------------------------------------
|
||||
@section{Errors}
|
||||
@itemize[
|
||||
@item{HTdP Teachpacks are added to a student's program by clicking on the
|
||||
``Language'' menu and selecting ``add Teachpack''. Students can then install a
|
||||
new Teachpack by clicking ``Add Teachpack to List'' and choosing the Teachpack
|
||||
file from the filesystem.}
|
||||
|
||||
@defmodule[htdp/error]
|
||||
@item{HTdP Libraries are brought into the student's program using a
|
||||
@racket[require] statement.}]
|
||||
|
||||
To provide uniform error messages from the TeachPacks, this module
|
||||
provides several functions:
|
||||
Under the hood, HTdP Teachpacks and HTdP Libraries are implemented the same way,
|
||||
using normal Racket @secref[#:doc '(lib "scribblings/guide/module.scrbl") "modules"].
|
||||
|
||||
@defproc[(check-arg) void?]{
|
||||
}
|
||||
When implementing an extension intended for students, pay a special attention to
|
||||
the error messages. The error messages of DrRacket's teaching languages go to
|
||||
great length to ensure that students are never confronted with messages that
|
||||
uses vocabulary or phrases the students has not learned yet. The teaching languages
|
||||
also ensure that students cannot stumble by accident onto challenging or
|
||||
confusing features intended for professional or for higher-level students.
|
||||
|
||||
@defproc[(check-arity) void?]{
|
||||
}
|
||||
This manual describes library support for authors of HTdP Teachpacks, libraries,
|
||||
and customized teaching languages. Use the HTdP
|
||||
@seclink["error-reporting"]{error reporting functions} to create error messages
|
||||
that integrate smoothly with those of the teaching languages. Before composing
|
||||
new error messages, we recommend you read the @seclink["error-guidelines"]{error
|
||||
message composition guidelines} that informed the design of the error messages
|
||||
of DrRacket's teaching languages.
|
||||
|
||||
@defproc[(check-proc) void?]{
|
||||
}
|
||||
@local-table-of-contents[#:style 'immediate-only]
|
||||
|
||||
@defproc[(check-result) void?]{
|
||||
}
|
||||
|
||||
@defproc[(check-list-list) void?]{
|
||||
}
|
||||
@include-section["error-composition.scrbl"]
|
||||
|
||||
@defproc[(check-color) void?]{
|
||||
}
|
||||
|
||||
@defproc[(check-fun-res) void?]{
|
||||
}
|
||||
|
||||
@defproc[(check-dependencies) void?]{
|
||||
}
|
||||
|
||||
@defproc[(natural?) void?]{
|
||||
}
|
||||
|
||||
@defproc[(find-non) void?]{
|
||||
}
|
||||
|
||||
@defproc[(tp-exn?) void?]{
|
||||
}
|
||||
|
||||
@defproc[(number->ord) void?]{
|
||||
}
|
||||
|
||||
@section{Testing}
|
||||
|
||||
@; -----------------------------------------------------------------------------
|
||||
@defmodule[htdp/testing #:use-sources (test-engine/scheme-tests)]
|
||||
|
||||
The library re-exports the following identifiers from test-engine/scheme-tests:
|
||||
|
||||
@racket[build-test-engine]
|
||||
@racket[builder]
|
||||
@racket[display-results]
|
||||
@racket[error-handler]
|
||||
@racket[exn:fail:wish]
|
||||
@racket[generate-report]
|
||||
@racket[get-test-engine]
|
||||
@racket[reset-tests]
|
||||
@racket[run-tests]
|
||||
@racket[scheme-test-data]
|
||||
@racket[signature-test-info%]
|
||||
@include-section["error-reporting.scrbl"]
|
||||
@include-section["testing.scrbl"]
|
||||
@include-section["htdp-lib.scrbl"]
|
||||
|
|
|
@ -1,174 +0,0 @@
|
|||
#lang scribble/doc
|
||||
@(require scribble/manual
|
||||
scribble/eval
|
||||
(for-label scheme/base
|
||||
scheme/contract
|
||||
scheme/class
|
||||
scheme/gui/base
|
||||
lang/posn
|
||||
lang/imageeq
|
||||
lang/prim))
|
||||
|
||||
@(define htdp @italic{How to Design Programs})
|
||||
@(define (htdp-ref s) @secref[#:doc '(lib "scribblings/htdp-langs/htdp-langs.scrbl") s])
|
||||
|
||||
@title{HtDP Languages as Libraries}
|
||||
|
||||
@; ------------------------------------------------------------
|
||||
@section{@italic{HtDP} Beginning Student}
|
||||
|
||||
@defmodule[lang/htdp-beginner]
|
||||
|
||||
The @racketmodname[lang/htdp-beginner] module provides the Beginning
|
||||
Student language for @|htdp|; see @htdp-ref["beginner"].
|
||||
|
||||
@; ------------------------------------------------------------
|
||||
@section{@italic{HtDP} Beginning Student with Abbreviations}
|
||||
|
||||
@defmodule[lang/htdp-beginner-abbr]
|
||||
|
||||
The @racketmodname[lang/htdp-beginner-abbr] module provides the
|
||||
Beginning Student with Abbreviations language for @|htdp|; see
|
||||
@htdp-ref["beginner-abbr"].
|
||||
|
||||
@; ------------------------------------------------------------
|
||||
@section{@italic{HtDP} Intermediate Student}
|
||||
|
||||
@defmodule[lang/htdp-intermediate]
|
||||
|
||||
The @racketmodname[lang/htdp-intermediate] module provides the
|
||||
Intermediate Student language for @|htdp|; see
|
||||
@htdp-ref["intermediate"].
|
||||
|
||||
@; ------------------------------------------------------------
|
||||
@section{@italic{HtDP} Intermediate Student with Lambda}
|
||||
|
||||
@defmodule[lang/htdp-intermediate-lambda]
|
||||
|
||||
The @racketmodname[lang/htdp-intermediate-lambda] module provides the
|
||||
Intermediate Student with Lambda language for @|htdp|; see
|
||||
@htdp-ref["intermediate-lam"].
|
||||
|
||||
@; ------------------------------------------------------------
|
||||
@section{@italic{HtDP} Advanced Student}
|
||||
|
||||
@defmodule[lang/htdp-advanced]
|
||||
|
||||
The @racketmodname[lang/htdp-advanced] module provides the Advanced
|
||||
Student language for @|htdp|; see @htdp-ref["advanced"].
|
||||
|
||||
@; ------------------------------------------------------------
|
||||
@section{Pretty Big Text (Legacy Language)}
|
||||
|
||||
@defmodule[lang/plt-pretty-big-text]
|
||||
|
||||
The @racketmodname[lang/plt-pretty-big-text] module is similar to the
|
||||
@italic{HtDP} Advanced Student language, but with more of Racket's
|
||||
libraries in legacy form. It provides the bindings of
|
||||
@racketmodname[mzscheme],
|
||||
@racketmodname[mzlib/etc], @racketmodname[mzlib/file],
|
||||
@racketmodname[mzlib/list], @racketmodname[mzlib/class],
|
||||
@racketmodname[mzlib/unit], @racketmodname[mzlib/include],
|
||||
@racketmodname[mzlib/defmacro], @racketmodname[mzlib/pretty],
|
||||
@racketmodname[mzlib/string], @racketmodname[mzlib/thread],
|
||||
@racketmodname[mzlib/math], @racketmodname[mzlib/match],
|
||||
@racketmodname[mzlib/shared], and @racketmodname[lang/posn].
|
||||
|
||||
@; ------------------------------------------------------------
|
||||
|
||||
@section{Pretty Big (Legacy Language)}
|
||||
|
||||
@defmodule[lang/plt-pretty-big]
|
||||
|
||||
The @racketmodname[lang/plt-pretty-big] module extends
|
||||
@racket[lang/plt-pretty-big-text] with @racketmodname[scheme/gui/base]
|
||||
and @racketmodname[lang/imageeq]. This language corresponds to the
|
||||
@onscreen{Pretty Big} legacy language in DrRacket.
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
@section{@racket[posn]s in @italic{HtDP} Languages}
|
||||
|
||||
@defmodule[lang/posn]
|
||||
|
||||
@defstruct[posn ([x any/c] [y any/c])]{
|
||||
|
||||
The @racket[posn] structure type that is also provided by
|
||||
@racket[lang/htdp-beginner].}
|
||||
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
@section{Image Equality in @italic{HtDP} Languages}
|
||||
|
||||
@defmodule[lang/imageeq]
|
||||
|
||||
@defproc[(image=? [i1 (is-a?/c image-snip%)]
|
||||
[i2 (is-a?/c image-snip%)])
|
||||
boolean?]{
|
||||
|
||||
The image-comparison operator that is also provided by
|
||||
@racket[lang/htdp-beginner].}
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
@section{Primitives in @italic{HtDP} Beginner}
|
||||
|
||||
@defmodule[lang/prim]
|
||||
|
||||
The @racketmodname[lang/prim] module several syntactic forms for
|
||||
use by the implementors of teachpacks, when the teachpack is to be
|
||||
used with the @|htdp| Beginner Student
|
||||
languages. In Beginner Student, primitive names (for built-in
|
||||
procedures) are distinguished from other types of expressions, so that
|
||||
they can be syntactically restricted to application positions.
|
||||
|
||||
@defform[(define-primitive id proc-id)]{
|
||||
|
||||
Defines @racket[id] to be a primitive operator whose implementation
|
||||
is @racket[proc-id], and that takes no procedures as
|
||||
arguments. Normally, @racket[id] is exported from the teachpack and
|
||||
@racket[proc-id] is not.}
|
||||
|
||||
@defform[(provide-primitive id)]{
|
||||
|
||||
Like @racket[define-primitive], but the existing function @racket[id] is
|
||||
exported as the primitive operator named @racket[id]. An alternative
|
||||
to @racket[define-primitive].}
|
||||
|
||||
@defform[(provide-primitives id ...)]{
|
||||
|
||||
Multiple-identifier version of @racket[provide-primitive].}
|
||||
|
||||
@defform[(define-higher-order-primitive id proc-id (arg ...))]{
|
||||
|
||||
Defines @racket[id] to be a primitive operator whose implementation is
|
||||
@racket[proc-id]. Normally, @racket[id] is exported from the teachpack and
|
||||
@racket[proc-id] is not.
|
||||
|
||||
For each non-procedure argument, the corresponding @racket[arg] should be
|
||||
an underscore. For each procedure argument, the corresponding @racket[arg]
|
||||
should be the usual name of the procedure.
|
||||
|
||||
@as-examples[
|
||||
@racketblock[
|
||||
(define-higher-order-primitive convert-gui convert-gui/proc (f2c))
|
||||
]]
|
||||
}
|
||||
|
||||
@defform[(provide-higher-order-primitive id (arg ...))]{
|
||||
|
||||
Like @racket[define-higher-order-primitive], but the existing function
|
||||
@racket[id] is exported as the primitive operator named
|
||||
@racket[id]. An alternative to @racket[define-higher-order-primitive].}
|
||||
|
||||
@defform[(first-order->higher-order expr)]{
|
||||
|
||||
If @racket[expr] is an identifier for a first-order function (either a
|
||||
primitive or a function defined within Beginner Student), produces the
|
||||
function as a value; otherwise, the form is equivalent to
|
||||
@racket[expr].
|
||||
|
||||
This form is mainly useful for implementing syntactic forms that, like
|
||||
the application of a higher-order primitive, allow first-order bindings
|
||||
to be used in an expression position.}
|
|
@ -18,4 +18,3 @@
|
|||
(string-constant how-to-design-programs)
|
||||
(string-constant beginning-student))))
|
||||
|
||||
(define scribblings '(("htdp-lib.scrbl")))
|
||||
|
|
|
@ -564,7 +564,6 @@ plt-extras :+= (package: "lang/" #:docs "htdp-langs/")
|
|||
;; -------------------- htdp, tests, teachpacks
|
||||
plt-extras :+=
|
||||
(package: "htdp/")
|
||||
(doc: "htdp-lib")
|
||||
(- (package: "teachpack/") (collects: "teachpack/deinprogramm/"))
|
||||
(- (package: "2htdp/")
|
||||
"uchat/") ; Matthias doesn't want this in now
|
||||
|
|
|
@ -176,7 +176,6 @@
|
|||
(mysterx "*...!" steck "MysterX: Using Windows COM Objects in Scheme")
|
||||
(mzcom "*...!" steck "MzCOM: Scheme as a Windows COM Object")
|
||||
(srfi "*...!" plt "SRFIs: Libraries")
|
||||
(htdp-lib "*...!" plt "HtDP: Languages as Libraries")
|
||||
(swindle "*...!" plt "Swindle")
|
||||
(syntax "*...!" plt "Syntax: Meta-Programming Helpers")
|
||||
(typed-scheme "*...!" samth "Typed Scheme: Scheme with Static Types")
|
||||
|
|
|
@ -1,190 +0,0 @@
|
|||
#lang scribble/doc
|
||||
@(require scribble/manual scribble/decode (for-label racket/base))
|
||||
|
||||
@title[#:tag "error-guidelines"]{
|
||||
Error Message Composition Guidelines for Student Languages}
|
||||
|
||||
This section lists some guidelines for writing good error messages for
|
||||
novices, as informed by @seclink["research"]{our research}. Please
|
||||
follow these guidelines when you write code that is intended for
|
||||
beginners, including libraries and teachpacks. It ensures that error
|
||||
messages from your code fits messages from the student languages and
|
||||
from other teachpacks.
|
||||
|
||||
@(define (samp . text) @splice[@list{@emph{``@splice[text]''}}])
|
||||
@(define (word . text) @splice[@list{‘@splice[text]’}])
|
||||
|
||||
@section{General Guidelines}
|
||||
|
||||
@itemize[
|
||||
@item{Frustrated students will peer at the error message for clues on
|
||||
how to proceed. Avoid offering hints, and avoid proposing any
|
||||
specific modification. Students will follow well-meaning-but-wrong
|
||||
advice uncritically, if only because they have no reason to doubt
|
||||
the authoritative voice of the tool.}
|
||||
|
||||
@item{Be concise and clear. Students give up reading error messages
|
||||
if the text is too long, uses obscure words, or employs difficult
|
||||
grammar.}]
|
||||
|
||||
@section{Message Structure and Form}
|
||||
|
||||
@itemize[
|
||||
@item{Start the message with the name of the construct whose
|
||||
constraint is being violated, followed by a colon.}
|
||||
|
||||
@item{State the constraint that was violated (@samp{expected a...}),
|
||||
then contrast with what was found. For example, @samp{this function
|
||||
expects two arguments, but found only one}. If needed, explain how
|
||||
what was found fails to satisfy the constraint. Write somewhat
|
||||
anthropomorphically with an objective voice that is neither friendly
|
||||
nor antagonistic.}
|
||||
|
||||
@item{If an expression contains multiple errors, report the leftmost
|
||||
error first. E.g., the error in @racket{(define 1 2 3)} is
|
||||
@samp{expected the variable name, but found a number}, not
|
||||
@samp{expected 2 parts after define, but found 3}. Before raising
|
||||
an error about a sub-part of a macro, call
|
||||
@racket[syntax-local-expand-expression] on sub-expressions to its
|
||||
left, so that such errors are shown first.}
|
||||
|
||||
@item{State the number of parts instead of saying @samp{found too many
|
||||
parts}. Write the code necessary to make plurals agree.}]
|
||||
|
||||
@section{Vocabulary}
|
||||
|
||||
@subsection{Permitted Words}
|
||||
|
||||
Use only the following vocabulary words to describe code:
|
||||
|
||||
@nested{@word{function}, @word{variable}, @word{argument},
|
||||
@word{function body}, @word{expression}, @word{part}, @word{clause},
|
||||
@word{top level}, @word{structure name}, @word{type name}, @word{field
|
||||
name}, @word{binding}.}
|
||||
|
||||
@itemize[
|
||||
@item{Use @word{binding} for the square-braced pair in a @racket{let}
|
||||
and similar binding forms.}
|
||||
|
||||
@item{Use @word{argument} for actual arguments and @word{variable} for
|
||||
formal arguments in the body of a definition.}
|
||||
|
||||
@item{Use @word{part} when speaking about an s-expression that is not
|
||||
an expression, either because it is malformed, because it occurs in
|
||||
a non-expression position, or because it is a valid piece of syntax
|
||||
for a macro invocation. A well-formed and well-placed call to a
|
||||
function, primitive, or macro is not a @word{part}, it is an
|
||||
@word{expression}.}]
|
||||
|
||||
@subsection{Prohibited Words}
|
||||
|
||||
These guidelines use few terms intentionally, emphasizing commonality
|
||||
among concepts rather than technical precision (which most students do
|
||||
not appreciate anyway).
|
||||
|
||||
@tabular[
|
||||
@list[
|
||||
@list[@para{@bold{Instead of}}
|
||||
@para{@bold{Use}}]
|
||||
@list[@para{procedure, primitive name, primitive operator, predicate,
|
||||
selector, constructor}
|
||||
@para{@samp{function}''}]
|
||||
@list[@para{s-expression}
|
||||
@para{@samp{expression}}]
|
||||
@list[@para{identifier}
|
||||
@para{@samp{argument} or @samp{variable}, depending on the use
|
||||
in the program}]
|
||||
@list[@para{defined name}
|
||||
@para{@samp{function} or @samp{variable}}]
|
||||
@list[@para{sequence}
|
||||
@para{@samp{at least one (in parentheses)}}]
|
||||
@list[@para{function header}
|
||||
@para{@samp{after define}, @samp{after the name},
|
||||
@samp{after the first argument}, ...}]
|
||||
@list[@para{keyword, form, syntax}
|
||||
@para{mention the construct directly by name, such as
|
||||
@samp{expected a variable but found a cond}. Use @samp{syntax}
|
||||
only when talking about many constructs in aggregate.}]
|
||||
@list[@para{built-in} @para{Nothing --- avoid this term}]
|
||||
@list[@para{macro} @para{Nothing --- avoid this term}]]]
|
||||
|
||||
@subsection{General Vocabulary Guidelines}
|
||||
|
||||
@itemize[
|
||||
@item{Avoid modifiers that are not necessary to disambiguate. Write
|
||||
@word{variable} instead of @word{local variable}, @word{defined
|
||||
variable}, or @word{input variable}. Write @word{clause} instead of
|
||||
@word{question-answer clause}. If they appear necessary for
|
||||
disambiguation, try to find some other way to achieve this (and drop
|
||||
the modifier).}
|
||||
|
||||
@item{When introducing macros with sub-parts, reuse existing
|
||||
vocabulary words, such as @word{clause} or @word{binding} (if
|
||||
appropriate), or just @word{part}, instead of defining new terms.}
|
||||
|
||||
@item{Use @word{name} only when describing the syntax of a definition
|
||||
form. For example, the define form in BSL should say @samp{expected
|
||||
at least one variable after the function name}. Outside of the
|
||||
definition form, simply use the word @word{function} rather than
|
||||
distinguish between (1) a function, (2) the variable that binds the
|
||||
function, and (3) the name of that variable.
|
||||
|
||||
[Rationale: Students learn this distinction when they learn about
|
||||
lambda. The first is the lambda implicit in the definition, the
|
||||
second is the variable introduced by the definition that can appear
|
||||
as the first argument to @racket{set!}, the third is the particular
|
||||
sequence of letters. But BSL should avoid this complexity, and
|
||||
ASL’s error messages should maintain consistency with BSL.]}
|
||||
|
||||
@item{Avoid introducing technical vocabulary, even if well-known to a
|
||||
mathematician.}]
|
||||
|
||||
@section{Punctuation}
|
||||
|
||||
@itemize[
|
||||
@item{Do not use any punctuation beyond those of the normal English
|
||||
language. Do not write @litchar{<>} around type names, and do not
|
||||
write quotes around keywords.}]
|
||||
|
||||
@section{Runtime Behavior}
|
||||
|
||||
@itemize[
|
||||
@item{When specifying a function's behavior, say @samp{the function
|
||||
takes ... and returns ...}}
|
||||
|
||||
@item{When describing a contract violation, say @samp{the function
|
||||
expects ... but received ...}}
|
||||
|
||||
@item{As much as possible, identify expressions by the value they
|
||||
evaluate to, e.g. @samp{the value of @racket{(f x)} is 5}. If it is
|
||||
necessary to explicate evaluation times, the context discusses
|
||||
mutable state or order of evaluation, then say that the expressions
|
||||
@samp{evaluate to} a value. Function calls are a special case of
|
||||
expression. Prefer @samp{the function call returns}, instead of
|
||||
@samp{it evaluates to}, except when trying to draw attention to the
|
||||
evaluation of the arguments.}]
|
||||
|
||||
@section[#:tag "research"]{Supporting Research}
|
||||
|
||||
These guidelines arose from a collections of research studies held at
|
||||
the Worcester Polytechnic Institute, Brown University, and Northeastern
|
||||
University. Further experiment details and results are described in:
|
||||
@itemize[
|
||||
@item{@hyperlink["http://www.cs.brown.edu/~sk/Publications/Papers/Published/mfk-mind-lang-novice-inter-error-msg/"]{
|
||||
Mind Your Language: On Novices' Interactions with Error
|
||||
Messages}
|
||||
|
||||
This paper reports on a series of studies that explore beginning
|
||||
students' interactions with the vocabulary and source-expression
|
||||
highlighting in DrRacket. Our findings demonstrate that the error
|
||||
message DrRacket's old error messages significantly failed to convey
|
||||
information accurately to students.}
|
||||
|
||||
@item{@hyperlink["http://www.cs.brown.edu/~sk/Publications/Papers/Published/mfk-measur-effect-error-msg-novice-sigcse/"]{
|
||||
Measuring the Effectiveness of Error Messages Designed for
|
||||
Novice Programmers}
|
||||
|
||||
This paper presents a fine-grained grading rubric for evaluating the
|
||||
performance of individual error messages. We applied the rubric to
|
||||
a course worth of student work, which allowed us to characterize
|
||||
some ways error messages fail.}]
|
|
@ -27,5 +27,3 @@ This chapter covers the teachpacks for @italic{How to Design Programs}.
|
|||
@; removed: @include-section["htdc/scribblings/htdc.scrbl"]
|
||||
|
||||
@include-section["2htdp/scribblings/2htdp.scrbl"]
|
||||
|
||||
@include-section["error-composition.scrbl"]
|
Loading…
Reference in New Issue
Block a user