From 2e536dc70e5f2bbf82dc740eb9b0e5540178ce1f Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 15 Jun 2007 01:59:06 +0000 Subject: [PATCH] doc work, and also generalize normalize-definition to work with opts and kws svn: r6665 --- collects/scribble/base-render.ss | 10 +- collects/scribble/basic.ss | 5 +- collects/scribble/html-render.ss | 5 +- collects/scribble/struct.ss | 44 +++-- collects/scribblings/guide/apply.scrbl | 59 +++---- collects/scribblings/guide/binding.scrbl | 2 +- collects/scribblings/guide/data.scrbl | 9 +- .../scribblings/guide/define-struct.scrbl | 8 +- collects/scribblings/guide/define.scrbl | 152 ++++++++++++++++-- collects/scribblings/guide/for.scrbl | 8 +- collects/scribblings/guide/forms.scrbl | 2 +- collects/scribblings/guide/guide.scrbl | 10 +- collects/scribblings/guide/lambda.scrbl | 30 ++-- collects/scribblings/guide/lists.scrbl | 60 +++---- collects/scribblings/guide/named-let.scrbl | 6 +- .../scribblings/guide/simple-syntax.scrbl | 104 ++++++------ collects/scribblings/guide/truth.scrbl | 8 +- collects/scribblings/guide/welcome.scrbl | 10 +- collects/scribblings/new-lambda.ss | 48 +++--- collects/scribblings/quick/quick.scrbl | 107 ++++++------ collects/scribblings/reference/syntax.scrbl | 3 + collects/scribblings/scribble/basic.scrbl | 3 + collects/scribblings/scribble/manual.scrbl | 6 +- collects/scribblings/scribble/struct.scrbl | 8 + collects/syntax/define.ss | 99 +++++++++--- collects/syntax/doc.txt | 8 +- 26 files changed, 520 insertions(+), 294 deletions(-) diff --git a/collects/scribble/base-render.ss b/collects/scribble/base-render.ss index 23503bb4c9..226820f71f 100644 --- a/collects/scribble/base-render.ss +++ b/collects/scribble/base-render.ss @@ -34,6 +34,14 @@ (substring s 0 (sub1 (string-length s)))) sep))) + (define/public (strip-aux content) + (cond + [(null? content) null] + [(aux-element? (car content)) + (strip-aux (cdr content))] + [else (cons (car content) + (strip-aux (cdr content)))])) + ;; ---------------------------------------- ;; global-info collection @@ -218,7 +226,7 @@ (null? (element-content i))) (let ([v (lookup part ht (link-element-tag i))]) (if v - (render-content (car v) part ht) + (render-content (strip-aux (car v)) part ht) (render-content (list "[missing]") part ht)))] [(element? i) (render-content (element-content i) part ht)] diff --git a/collects/scribble/basic.ss b/collects/scribble/basic.ss index 071635f0f5..624837b4ed 100644 --- a/collects/scribble/basic.ss +++ b/collects/scribble/basic.ss @@ -69,7 +69,7 @@ ;; ---------------------------------------- (provide hspace - elem + elem aux-elem italic bold tt span-class subscript superscript) @@ -80,6 +80,9 @@ (define/kw (elem #:body str) (make-element #f (decode-content str))) + (define/kw (aux-elem #:body s) + (make-aux-element #f (decode-content s))) + (define/kw (italic #:body str) (make-element 'italic (decode-content str))) diff --git a/collects/scribble/html-render.ss b/collects/scribble/html-render.ss index 25382df349..f629772215 100644 --- a/collects/scribble/html-render.ss +++ b/collects/scribble/html-render.ss @@ -31,6 +31,7 @@ install-file get-dest-directory format-number + strip-aux lookup) (define/override (get-suffix) #".html") @@ -71,7 +72,7 @@ (content "text-html; charset=utf-8"))) ,@(let ([c (part-title-content d)]) (if c - `((title ,@(format-number number '(nbsp)) ,@(render-content c d ht))) + `((title ,@(format-number number '(nbsp)) ,(content->string c this d ht))) null)) (link ((rel "stylesheet") (type "text/css") @@ -156,7 +157,7 @@ `((class ,(element-style e))) null)) ,@(if (null? (element-content e)) - (render-content (cadr dest) part ht) + (render-content (strip-aux (cadr dest)) part ht) (render-content (element-content e) part ht)))) (begin (fprintf (current-error-port) "Undefined link: ~s~n" (link-element-tag e)) ; XXX Add source info `((font ((class "badlink")) diff --git a/collects/scribble/struct.ss b/collects/scribble/struct.ss index 07146395e9..fe5ff5c284 100644 --- a/collects/scribble/struct.ss +++ b/collects/scribble/struct.ss @@ -76,6 +76,7 @@ [(index-element element) ([tag tag?] [plain-seq (listof string?)] [entry-seq list?])] + [(aux-element element) ()] ;; specific renders support other elements, especially strings [collected-info ([number (listof (or/c false/c integer?))] @@ -132,22 +133,35 @@ (provide content->string) - (define (content->string c) - (apply string-append - (map (lambda (e) - (element->string e)) - c))) + (define content->string + (case-lambda + [(c) (c->s c element->string)] + [(c renderer sec ht) (c->s c (lambda (e) + (element->string e renderer sec ht)))])) - (define (element->string c) - (cond - [(element? c) (content->string (element-content c))] - [(string? c) c] - [else (case c - [(ndash) "--"] - [(ldquo rdquo) "\""] - [(rsquo) "'"] - [(rarr) "->"] - [else (format "~s" c)])])) + (define (c->s c do-elem) + (apply string-append + (map do-elem c))) + + (define element->string + (case-lambda + [(c) + (cond + [(element? c) (content->string (element-content c))] + [(string? c) c] + [else (case c + [(ndash) "--"] + [(ldquo rdquo) "\""] + [(rsquo) "'"] + [(rarr) "->"] + [else (format "~s" c)])])] + [(c renderer sec ht) + (cond + [(element? c) (content->string (element-content c) renderer sec ht)] + [(delayed-element? c) + (content->string (force-delayed-element c renderer sec ht) + renderer sec ht)] + [else (element->string c)])])) ) diff --git a/collects/scribblings/guide/apply.scrbl b/collects/scribblings/guide/apply.scrbl index 20498c979d..3d036d72be 100644 --- a/collects/scribblings/guide/apply.scrbl +++ b/collects/scribblings/guide/apply.scrbl @@ -3,7 +3,7 @@ @require[(lib "eval.ss" "scribble")] @require["guide-utils.ss"] -@title[#:tag "guide:application"]{Procedure Applications} +@title[#:tag "guide:application"]{Function Calls@aux-elem{ (Procedure Applications)}} An expression of the form @@ -11,16 +11,18 @@ An expression of the form (_proc-expr _arg-expr ...) ] -is a procedure application when @scheme[_proc-expr] is not an -identifier that is bound as a transformer. +is a function call---also known as a @defterm{procedure +application}---when @scheme[_proc-expr] is not an identifier that is +bound as a syntax transformer (such as @scheme[if] or +@scheme[define]). @section{Evaluation Order and Arity} -A procedure application is evaluated by first evaluating the +A function call is evaluated by first evaluating the @scheme[_proc-expr] and all @scheme[_arg-expr]s in order (left to -right). Then, if @scheme[_proc-expr] produced a procedure that accepts -as many arguments as supplied @scheme[_arg-expr]s, the procedure is -applied. Otherwise, an exception is raised. +right). Then, if @scheme[_proc-expr] produced a function that accepts +as many arguments as supplied @scheme[_arg-expr]s, the function is +called. Otherwise, an exception is raised. @examples[ (cons 1 null) @@ -29,17 +31,17 @@ applied. Otherwise, an exception is raised. (1 2 3) ] -Some procedures, such as @scheme[cons], accept a fixed number of -arguments. Some procedures, such as @scheme[list], accept any number -of arguments. Some procedures accept a range of argument counts; for +Some functions, such as @scheme[cons], accept a fixed number of +arguments. Some functions, such as @scheme[list], accept any number +of arguments. Some functions accept a range of argument counts; for example @scheme[substring] accepts either two or three arguments. A -procedure's @idefterm{arity} is the number(s) of arguments that it +function's @idefterm{arity} is the number of arguments that it accepts. @;------------------------------------------------------------------------ @section[#:tag "guide:keyword-args"]{Keyword Arguments} -Some procedures accept @defterm{keyword arguments} in addition to +Some functions accept @defterm{keyword arguments} in addition to by-position arguments. For that case, an @scheme[_arg] can be an @scheme[_arg-keyword _arg-expr] sequence instead of just a @scheme[_arg-expr]: @@ -56,7 +58,7 @@ For example, @schemeblock[(go "super.ss" #:mode 'fast)] -calls the procedure bound to @scheme[go] with @scheme["super.ss"] as a +calls the function bound to @scheme[go] with @scheme["super.ss"] as a by-position argument, and with @scheme['fast] as an argument associated with the @scheme[#:mode] keyword. A keyword is implicitly paired with the expression that follows it. @@ -70,7 +72,7 @@ expression to produce an argument value, and @scheme[#:fast] is not an expression. The order of keyword @scheme[_arg]s determines the order in which -@scheme[_arg-expr]s are evaluated, but a procedure accepts keyword +@scheme[_arg-expr]s are evaluated, but a function accepts keyword arguments independent of their position in the argument list. The above call to @scheme[go] can be equivalently written @@ -79,13 +81,12 @@ above call to @scheme[go] can be equivalently written @refdetails["mz:application"]{procedure applications} @;------------------------------------------------------------------------ -@section[#:tag "guide:apply"]{The @scheme[apply] Procedure} +@section[#:tag "guide:apply"]{The @scheme[apply] Function} -The syntax for procedure applications supports any number of -arguments, but a specific application expression always specifies a -fixed number of arguments. As a result, a procedure that takes a list -of arguments cannot directly apply a procedure like @scheme[+] to all -of the items in the list: +The syntax for function calls supports any number of arguments, but a +specific call always specifies a fixed number of arguments. As a +result, a function that takes a list of arguments cannot directly +apply a function like @scheme[+] to all of the items in the list: @def+int[ (define (avg lst) (code:comment #, @elem{doesn't work...}) @@ -101,9 +102,9 @@ of the items in the list: (avg '(1 2)) ] -The @scheme[apply] procedure offers a way around this restriction. It -takes a procedure and a @italic{list} arguments, and it applies the -procedure to the arguments: +The @scheme[apply] function offers a way around this restriction. It +takes a function and a @italic{list} arguments, and it applies the +function to the arguments: @def+int[ (define (avg lst) @@ -113,8 +114,8 @@ procedure to the arguments: (avg '(1 2 3 4)) ] -As a convenience, the @scheme[apply] procedure accepts additional -arguments between the procedure and the list. The additional arguments +As a convenience, the @scheme[apply] function accepts additional +arguments between the function and the list. The additional arguments are effectively @scheme[cons]ed onto the argument list: @def+int[ @@ -123,13 +124,13 @@ are effectively @scheme[cons]ed onto the argument list: (anti-sum '(1 2 3)) ] -The @scheme[apply] procedure supports only by-position arguments. To -apply a procedure with keyword arguments, use the -@scheme[keyword-apply] procedure, which accepts a procedure to apply +The @scheme[apply] function supports only by-position arguments. To +apply a function with keyword arguments, use the +@scheme[keyword-apply] function, which accepts a function to apply and three lists. The first two lists are in parallel, where the first list contains keywords (sorted by @scheme[keyword<]), and the second list contains a corresponding argument for each keyword. The third -list contains by-position procedure arguments, as for @scheme[apply]. +list contains by-position function arguments, as for @scheme[apply]. @schemeblock[ (keyword-apply go diff --git a/collects/scribblings/guide/binding.scrbl b/collects/scribblings/guide/binding.scrbl index 66d6cd4ca9..5a2b2ce158 100644 --- a/collects/scribblings/guide/binding.scrbl +++ b/collects/scribblings/guide/binding.scrbl @@ -13,7 +13,7 @@ the language @schememodname[big], as in means that, within the module, the identifiers described in this guide have the the meaning described here: @scheme[cons] refers to the -procedure that creates a pair, @scheme[car] refers to the procedure +function that creates a pair, @scheme[car] refers to the function that extracts the first element of a pair, and so on. @margin-note{For information on the syntax of identifiers, see diff --git a/collects/scribblings/guide/data.scrbl b/collects/scribblings/guide/data.scrbl index 1f2f7eb3fe..dc6bfabca3 100644 --- a/collects/scribblings/guide/data.scrbl +++ b/collects/scribblings/guide/data.scrbl @@ -18,11 +18,12 @@ built-in datatypes for simple forms of data. @include-section["char-strings.scrbl"] @include-section["byte-strings.scrbl"] @include-section["symbols.scrbl"] +@include-section["keywords.scrbl"] @include-section["pairs.scrbl"] @include-section["vectors.scrbl"] -@include-section["boxes.scrbl"] @include-section["hash-tables.scrbl"] -@include-section["paths.scrbl"] -@include-section["regexps-data.scrbl"] -@include-section["keywords.scrbl"] +@include-section["boxes.scrbl"] @include-section["void-and-undef.scrbl"] + +@; @include-section["paths.scrbl"] +@; @include-section["regexps-data.scrbl"] diff --git a/collects/scribblings/guide/define-struct.scrbl b/collects/scribblings/guide/define-struct.scrbl index de1c7f3243..fb65c38567 100644 --- a/collects/scribblings/guide/define-struct.scrbl +++ b/collects/scribblings/guide/define-struct.scrbl @@ -4,7 +4,7 @@ @require[(lib "bnf.ss" "scribble")] @require["guide-utils.ss"] -@title{Programmer-Defined Datatypes} +@title[#:tag "guide:define-struct"]{Programmer-Defined Datatypes} This section introduces the @scheme[define-struct] form for creating your own datatypes. The class-based object system offers an alternate @@ -33,20 +33,20 @@ We explain one use of the @scheme[_struct-id] binding in the next section. In addition to defining @scheme[_struct-id], however, -@scheme[define-struct] also defines a number of procedures whose names +@scheme[define-struct] also defines a number of functions whose names are built from @scheme[_struct-id] and the @scheme[_field-id]s: @itemize{ @item{@schemeidfont{make-}@scheme[_struct-id] : a - @defterm{constructor} procedure that takes as many arguments as + @defterm{constructor} function that takes as many arguments as the number of @scheme[_field-id]s, and returns an instance of the structure type. @examples[(make-posn 1 2)]} @item{@scheme[_struct-id]@schemeidfont{?} : a @defterm{predicate} - procedure that takes a single argument and returns @scheme[#t] + function that takes a single argument and returns @scheme[#t] if it is an instance of the structure type, @scheme[#f] otherwise. diff --git a/collects/scribblings/guide/define.scrbl b/collects/scribblings/guide/define.scrbl index 13d42767ee..a50fb793b8 100644 --- a/collects/scribblings/guide/define.scrbl +++ b/collects/scribblings/guide/define.scrbl @@ -3,6 +3,8 @@ @require[(lib "eval.ss" "scribble")] @require["guide-utils.ss"] +@interaction-eval[(require (lib "string.ss"))] + @title{Definitions: @scheme[define]} A basic definition has the form @@ -18,9 +20,9 @@ salutation ] @;------------------------------------------------------------------------ -@section{Procedure Shorthand} +@section{Function Shorthand} -The @scheme[define] form also supports a shorthand for procedure +The @scheme[define] form also supports a shorthand for function definitions: @specform[(define (id arg ...) body ...+)]{} @@ -45,8 +47,9 @@ which is a shorthand for (greet "John" "Doe") ] -The procedure shorthand via @scheme[define] also supports a final -argument to collect extra arguments in a list: +The function shorthand via @scheme[define] also supports a ``rest'' +argument (i.e., a final argument to collect extra arguments in a +list): @specform[(define (id arg ... . rest-id) expr)]{} @@ -62,6 +65,65 @@ which is a shorthand (avg 1 2 3) ] +@;------------------------------------------------------------------------ +@section{Curried Function Shorthand} + +Consider the following @scheme[make-add-suffix] function that takes a +string and returns another function that takes a string. Normally, the +result of @scheme[make-add-suffix] would be sent to some other +function, but it could be called directly, like this: + +@def+int[ +(define make-add-suffix + (lambda (s2) + (lambda (s) (string-append s s2)))) + +((make-add-suffix "!") "hello") +] + +In a sense, the @scheme[make-add-suffix] function takes two arguments, +but it takes them one at a time. A function that takes some of its +arguments and returns a function to consume more is sometimes called a +@defterm{curried function}. + +Using the function-shorthand form of @scheme[define], +@scheme[make-add-suffix] can be written equivalently as + +@schemeblock[ +(define (make-add-suffix s2) + (lambda (s) (string-append s s2))) +] + +This shorthand reflects the shape of the function call +@scheme[(make-add-suffix "!")]. The @scheme[define] form further +supports a shorthand for defining curried functions that reflects +nested function calls: + +@def+int[ +(define ((make-add-suffix s2) s) + (string-append s s2)) +((make-add-suffix "!") "hello") +] +@defs+int[ +[(define louder (make-add-suffix "!")) + (define less-sure (make-add-suffix "?"))] +(less-sure "really") +(louder "really") +] + +The full syntax of the function shorthand for @scheme[define] is as follows: + +@specform/subs[(define (head args) body ...+) + ([head id + (head args)] + [args (code:line arg ...) + (code:line arg ... #, @schemeparenfont{.} rest-id)])]{} + +The expansion of this shorthand has one nested @scheme[lambda] form +for each @scheme[_head] in the definition, where the innermost +@scheme[_head] corresponds to the outermost @scheme[lambda]. + + @;------------------------------------------------------------------------ @section[#:tag "guide:multiple-values"]{Multiple Values and @scheme[define-values]} @@ -78,8 +140,8 @@ but @scheme[quotient/remainder] produces the same two values at once: As shown above, the REPL prints each result value on its own line. -Multiple-valued procedures can be implemented in terms of the -@scheme[values] procedure, which takes any number of values and +Multiple-valued functions can be implemented in terms of the +@scheme[values] function, which takes any number of values and returns them as the results: @interaction[ @@ -87,8 +149,10 @@ returns them as the results: ] @def+int[ (define (split-name name) - (let ([m (regexp-match #rx"^([^ ]*) (.*)$" name)]) - (values (list-ref m 1) (list-ref m 2)))) + (let ([parts (regexp-split " " name)]) + (if (= (length parts) 2) + (values (list-ref parts 0) (list-ref parts 1)) + (error "not a name")))) (split-name "Adam Smith") ] @@ -106,12 +170,74 @@ given surname ] -A @scheme[define] form (that is not a procedure shorthand) is -equivalent to a @scheme[define-values] form with a single @scheme[id]. +A @scheme[define] form (that is not a function shorthand) is +equivalent to a @scheme[define-values] form with a single @scheme[_id]. + +@refdetails["mz:define"]{definitions} @;------------------------------------------------------------------------ @section[#:tag "guide:intdefs"]{Internal Definitions} -When the grammar for a syntactic form specified @scheme[_body], then -the corresponding position in an instance of the grammar can be either -a definition or an expression. +When the grammar for a syntactic form specifies @scheme[_body], then +the corresponding form can be either a definition or an expression. +A definition as a @scheme[_body] is an @defterm{internal definition}. + +All internal definitions in a @scheme[_body] sequence must appear +before any expression, and the last @scheme[_body] must be an +expression. + +For example, the syntax of @scheme[lambda] is + +@specform[ +(lambda gen-formals + body ...+) +] + +so the following are valid instances of the grammar: + +@schemeblock[ +(lambda (f) (code:comment #, @elem{no definitions}) + (printf "running\n") + (f 0)) + +(lambda (f) (code:comment #, @elem{one definition}) + (define (log-it what) + (printf "~a\n")) + (log-it "running") + (f 0) + (log-it "done")) + +(lambda (f n) (code:comment #, @elem{two definitions}) + (define (call n) + (if (zero? n) + (log-it "done") + (begin + (log-it "running") + (f 0) + (call (- n 1))))) + (define (log-it what) + (printf "~a\n")) + (call f n)) +] + +Internal definitions in a particular @scheme[_body] sequence are +mutually recursive; that is, any definition can refer to any other +definition---as long as the reference isn't actually evaluated before +its definition takes place. If a definition is referenced too early, +the result is a special value @|undefined-const|. + +@defexamples[ +(define (weird) + (define x x) + x) +(weird) +] + +A sequence of internal definitions using just @scheme[define] is +easily translated to an equivalent @scheme[letrec] form (as introduced +in the next section). However, other definition forms can appear as a +@scheme[_body], including @scheme[define-struct] (see +@secref["guide:define-struct"]) or @scheme[define-syntax] (see +@secref["guide:macros"]). + +@refdetails/gory["mz:intdef-body"]{internal definitions} diff --git a/collects/scribblings/guide/for.scrbl b/collects/scribblings/guide/for.scrbl index a101b020bb..a2daa0ce5c 100644 --- a/collects/scribblings/guide/for.scrbl +++ b/collects/scribblings/guide/for.scrbl @@ -58,7 +58,7 @@ see the kinds of sequence generators that make interesting examples. @section[#:tag "guide:sequences"]{Sequence Constructors} -The @scheme[in-range] procedure generates a sequence of numbers, given +The @scheme[in-range] function generates a sequence of numbers, given an optional starting number (which defaults to @scheme[0]), a number before which the sequences ends, and an optional step (which defaults to @scheme[1]). @@ -76,7 +76,7 @@ to @scheme[1]). (printf " ~a " i)) ] -The @scheme[in-naturals] procedure is similar, except that the +The @scheme[in-naturals] function is similar, except that the starting number must be an exact non-negative integer (which defaults to @scheme[0]), the step is always @scheme[1], and there is no upper limit. A @scheme[for] loop using just @scheme[in-naturals] will never @@ -90,7 +90,7 @@ escapes. (display i))) ] -The @scheme[stop-before] and @scheme[stop-after] procedures construct +The @scheme[stop-before] and @scheme[stop-after] functions construct a new sequence given a sequence and a predicate. The new sequence is like the given sequence, but truncated either immediately before or immediately after the first element for which the predicate returns @@ -341,7 +341,7 @@ multiple values for the results. @section{Multiple-Valued Sequences} -In the same way that a procedure or expression can produce multiple +In the same way that a function or expression can produce multiple values, individual iterations of a sequence can produce multiple elements. For example, a hash table as a sequence generates two values for each iteration: a key and a value. diff --git a/collects/scribblings/guide/forms.scrbl b/collects/scribblings/guide/forms.scrbl index c4c44cb90e..823761eed0 100644 --- a/collects/scribblings/guide/forms.scrbl +++ b/collects/scribblings/guide/forms.scrbl @@ -42,7 +42,7 @@ convention implicitly defines the meaning of many meta-variables: sub-form; it will be parsed as either a local definition or an expression. A @scheme[_body] can parse as a definition only if it is not preceded by any expression, and the last - @scheme[_body] must be an expression.} + @scheme[_body] must be an expression; see also @secref["guide:intdefs"].} } diff --git a/collects/scribblings/guide/guide.scrbl b/collects/scribblings/guide/guide.scrbl index fdfe088281..c75e0eace6 100644 --- a/collects/scribblings/guide/guide.scrbl +++ b/collects/scribblings/guide/guide.scrbl @@ -62,7 +62,7 @@ using @idefterm{contracts}. @; ---------------------------------------------------------------------- -@section[#:tag "regexp"]{Regular-Expression Matching (Regexps)} +@section[#:tag "regexp"]{Regular-Expression Matching@aux-elem{ (Regexps)}} @; ---------------------------------------------------------------------- @@ -70,11 +70,11 @@ using @idefterm{contracts}. @; ---------------------------------------------------------------------- -@section[#:tag "units"]{Higher-Order Modules (Units)} +@section[#:tag "units"]{Units (Higher-Order Modules)} @; ---------------------------------------------------------------------- -@section[#:tag "macros"]{Syntactic Extension (Modules and Macros)} +@section[#:tag "guide:macros"]{Syntactic Extension@aux-elem{ (Modules and Macros)}} @; ---------------------------------------------------------------------- @@ -101,7 +101,7 @@ using @idefterm{contracts}. @; ---------------------------------------------------------------------- -@section[#:tag "ffi"]{Foreign-Function Interface (FFI)} +@section[#:tag "ffi"]{Foreign-Function Interface@aux-elem{ (FFI)}} @; ---------------------------------------------------------------------- @@ -109,7 +109,7 @@ using @idefterm{contracts}. @; ---------------------------------------------------------------------- -@section[#:tag "gui"]{Graphical User Interfaces (GUIs)} +@section[#:tag "gui"]{Graphical User Interfaces@aux-elem{ (GUIs)}} @; ---------------------------------------------------------------------- diff --git a/collects/scribblings/guide/lambda.scrbl b/collects/scribblings/guide/lambda.scrbl index c8fb3f1fdf..a61a4d0b57 100644 --- a/collects/scribblings/guide/lambda.scrbl +++ b/collects/scribblings/guide/lambda.scrbl @@ -3,9 +3,9 @@ @require[(lib "eval.ss" "scribble")] @require["guide-utils.ss"] -@title[#:tag "guide:lambda"]{Procedures: @scheme[lambda]} +@title[#:tag "guide:lambda"]{Functions@aux-elem{ (Procedures)}: @scheme[lambda]} -Such a @scheme[lambda] expression creates a procedure. In the simplest +Such a @scheme[lambda] expression creates a function. In the simplest case, a @scheme[lambda] expression has the form @specform[ @@ -37,7 +37,7 @@ A @scheme[lambda] expression can also have the form That is, a @scheme[lambda] expression can have a single @scheme[_rest-id] that is not surrounded by parentheses. The resulting -procedure accepts any number of arguments, and the arguments are put +function accepts any number of arguments, and the arguments are put into a list bound to @scheme[_rest-id]. @examples[ @@ -48,8 +48,8 @@ into a list bound to @scheme[_rest-id]. 1 2 3) ] -Procedures with a @scheme[_rest-id] often use @scheme[apply] to call -another procedure that accepts any number of arguments. +Functions with a @scheme[_rest-id] often use @scheme[apply] to call +another function that accepts any number of arguments. @margin-note{See @secref["guide:apply"] for more information on @scheme[apply].} @@ -71,7 +71,7 @@ with a @scheme[_rest-id]: body ...+) ] -The result of this form is a procedure that requires at least as many +The result of this form is a function that requires at least as many arguments as @scheme[_arg-id]s, and also accepts any number of additional arguments. @@ -85,7 +85,7 @@ additional arguments. ] A @scheme[_rest-id] variable is sometimes called a @defterm{rest -argument}, because it accepts the ``rest'' of the procedure arguments. +argument}, because it accepts the ``rest'' of the function arguments. @;------------------------------------------------------------------------ @section{Declaring Optional Arguments} @@ -179,9 +179,9 @@ specifies a keyword-based argument with a default value. ] The @scheme[lambda] form does not directly support the creation -of a procedure that accepts ``rest'' keywords. To construct a -procedure that accepts any and all keyword arguments, use -@scheme[make-keyword-procedure]. The procedure supplied to +of a function that accepts ``rest'' keywords. To construct a +function that accepts any and all keyword arguments, use +@scheme[make-keyword-procedure]. The function supplied to @scheme[make-keyword-procedure] receives keyword arguments through parallel lists in the first two (by-position) arguments, and then all by-position arguments from an application as the @@ -199,12 +199,12 @@ remaining by-position arguments. ((trace-wrap greet) "John" #:hi "Howdy") ] -@refdetails["mz:lambda"]{procedure expressions} +@refdetails["mz:lambda"]{function expressions} @;------------------------------------------------------------------------ -@section{Arity-Sensitive Procedures: @scheme[case-lambda]} +@section{Arity-Sensitive Functions: @scheme[case-lambda]} -The @scheme[case-lambda] form creates a procedure that can have +The @scheme[case-lambda] form creates a function that can have completely different behaviors depending on the number of arguments that are supplied. A case-lambda expression has the form @@ -218,7 +218,7 @@ that are supplied. A case-lambda expression has the form ] where each @scheme[[_formals _body ...+]] is analogous to @scheme[(lambda -_formals _body ...+)]. Applying a procedure produced by +_formals _body ...+)]. Applying a function produced by @scheme[case-lambda] is like applying a @scheme[lambda] for the first case that matches the number of given arguments. @@ -233,5 +233,5 @@ case that matches the number of given arguments. (greet) ] -A @scheme[case-lambda] procedure cannot directly support optional or +A @scheme[case-lambda] function cannot directly support optional or keyword arguments. diff --git a/collects/scribblings/guide/lists.scrbl b/collects/scribblings/guide/lists.scrbl index d62bc7ce08..60f1dc5763 100644 --- a/collects/scribblings/guide/lists.scrbl +++ b/collects/scribblings/guide/lists.scrbl @@ -14,7 +14,7 @@ Scheme is a dialect of the language Lisp, whose name originally stood for ``LISt Processor.'' The built-in list datatype remains a prominent feature of the language. -The @scheme[list] procedure takes any number of values and returns +The @scheme[list] function takes any number of values and returns a list containing the values: @interaction[(list "red" "green" "blue") @@ -29,7 +29,7 @@ parentheses are used for both expressions, such as @scheme[(list "red" DrScheme, parentheses for results are printed in blue, whereas parentheses for expressions are brown. -Many predefined procedures operate on lists. Here are a few examples: +Many predefined functions operate on lists. Here are a few examples: @interaction[ (code:line (length (list "a" "b" "c")) (code:comment #, @t{count the elements})) @@ -44,14 +44,14 @@ Many predefined procedures operate on lists. Here are a few examples: @section{Predefined List Loops} In addition to simple operations like @scheme[append], Scheme includes -procedures that iterate over the elements of a list. These iteration -procedures play much the same role as @tt{for} in Java and other -languages. The body of a Scheme iteration is packaged into a procedure +functions that iterate over the elements of a list. These iteration +functions play much the same role as @tt{for} in Java and other +languages. The body of a Scheme iteration is packaged into a function to be applied to each element, so the @scheme[lambda] form becomes -particularly handy in combination with iteration procedures. +particularly handy in combination with iteration functions. -Different list-iteration procedures combine iteration results in -different ways. The @scheme[map] procedure uses the per-element +Different list-iteration functions combine iteration results in +different ways. The @scheme[map] function uses the per-element results to create a new list: @interaction[ @@ -61,7 +61,7 @@ results to create a new list: (list "peanuts" "popcorn" "crackerjack")) ] -The @scheme[andmap] and @scheme[ormap] procedures combine the results +The @scheme[andmap] and @scheme[ormap] functions combine the results by @scheme[and]ing or @scheme[or]ing: @interaction[ @@ -70,7 +70,7 @@ by @scheme[and]ing or @scheme[or]ing: (ormap number? (list "a" "b" 6)) ] -The @scheme[filter] procedure keeps elements for which the body result +The @scheme[filter] function keeps elements for which the body result is true, and discards elements for which it is @scheme[#f]: @interaction[ @@ -79,8 +79,8 @@ is true, and discards elements for which it is @scheme[#f]: ] The @scheme[map], @scheme[andmap], @scheme[ormap], and @scheme[filter] -procedures can all handle multiple lists, instead of just a single -list. The lists must all have the same length, and the given procedure +functions can all handle multiple lists, instead of just a single +list. The lists must all have the same length, and the given function must accept one argument for each list: @interaction[ @@ -89,9 +89,9 @@ must accept one argument for each list: (list 6 3 7)) ] -The @scheme[foldl] procedure generalizes some iteration procedures. It -uses the per-element procedure to both process an element and combine -it with the ``current'' value, so the per-element procedure takes an +The @scheme[foldl] function generalizes some iteration functions. It +uses the per-element function to both process an element and combine +it with the ``current'' value, so the per-element function takes an extra first argument. Also, a starting ``current'' value must be provided before the lists: @@ -103,7 +103,7 @@ provided before the lists: ] Despite its generality, @scheme[foldl] is not as popular as the other -procedures. One reason is that @scheme[map], @scheme[ormap], +functions. One reason is that @scheme[map], @scheme[ormap], @scheme[andmap], and @scheme[filter] cover the most common kinds of list loops. @@ -115,7 +115,7 @@ are described in see @secref["guide:for"]. @;------------------------------------------------------------------------ @section{List Iteration from Scratch} -Although @scheme[map] and other iteration procedures predefined, they +Although @scheme[map] and other iteration functions predefined, they are not primitive in any interesting sense. You can write equivalent iterations using a handful of list primitives. @@ -136,7 +136,7 @@ non-empty list are ] To create a new node for a linked list---that is, to add to the front -of the list---use the @scheme[cons] procedure, which is short for +of the list---use the @scheme[cons] function, which is short for ``construct.'' To get an empty list to start with, use the @scheme[empty] constant: @@ -148,7 +148,7 @@ empty To process a list, you need to be able to distinguish empty lists from non-empty lists, because @scheme[first] and @scheme[rest] work only on -non-empty lists. The @scheme[empty?] procedure detects empty lists, +non-empty lists. The @scheme[empty?] function detects empty lists, and @scheme[cons?] detects non-empty lists: @interaction[ @@ -159,7 +159,7 @@ and @scheme[cons?] detects non-empty lists: ] With these pieces, you can write your own versions of the -@scheme[length] procedure, @scheme[map] procedure, and more. +@scheme[length] function, @scheme[map] function, and more. @defexamples[ (define (my-length lst) @@ -182,7 +182,7 @@ If the derivation of the above definitions is mysterious to you, consider reading @|HtDP|. If you are merely suspicious of the use of recursive calls instead of a looping construct, then read on. -Both the @scheme[my-length] and @scheme[my-map] procedures run in +Both the @scheme[my-length] and @scheme[my-map] functions run in @math{O(n)} time for a list of length @math{n}. This is easy to see by imagining how @scheme[(my-length (list "a" "b" "c"))] must evaluate: @@ -202,14 +202,14 @@ For a list with @math{n} elements, evalution will stack up @math{n} list is exhausted. You can avoid piling up additions by adding along the way. To -accumulate a length this way, we need a procedure that takes both a +accumulate a length this way, we need a function that takes both a list and the length of the list seem so far; the code below uses a -local procedure @scheme[iter] that accumulates the length in an +local function @scheme[iter] that accumulates the length in an argument @scheme[len]: @schemeblock[ (define (my-length lst) - (code:comment #, @elem{local procedure @scheme[iter]:}) + (code:comment #, @elem{local function @scheme[iter]:}) (define (iter lst len) (cond [(empty? lst) len] @@ -231,8 +231,8 @@ Now evaluation looks like this: The revised @scheme[my-length] runs in constant space, just as the evaluation steps above suggest. That is, when the result of a -procedure call, like @scheme[(iter (list "b" "c") 1)], is exactly the -result of some other procedure call, like @scheme[(iter (list "c") +function call, like @scheme[(iter (list "b" "c") 1)], is exactly the +result of some other function call, like @scheme[(iter (list "c") 2)], then the first one doesn't have to wait around for the second one, because that takes up space for no good reason. @@ -265,7 +265,7 @@ It turns out that if you write (f i))) ] -then the @scheme[for/list] form in the procedure both is expanded to +then the @scheme[for/list] form in the function both is expanded to essentially the same code as the @scheme[iter] local definition and use. The difference is merely syntactic convenience. @@ -291,7 +291,7 @@ tail-recursive programs automatically run the same as a loop, lead Scheme programmers to embrace recursive forms rather than avoid them. Suppose, for example, that you want to remove consecutive duplicates -from a list. While such a procedure can be written as a loop that +from a list. While such a function can be written as a loop that remembers the previous element for each iteration, a Scheme programmer would more likely just write the following: @@ -308,12 +308,12 @@ would more likely just write the following: (remove-dups (list "a" "b" "b" "b" "c" "c")) ] -In general, this procedure consumes @math{O(n)} space for an input +In general, this function consumes @math{O(n)} space for an input list of length @math{n}, but that's fine, since it produces an @math{O(n)} result. If the input list happens to be mostly consecutive duplicates, then the resulting list can be much smaller than @math{O(n)}---and @scheme[remove-dups] will also use much less than -@math{O(n)} space! The reason is that when the procedure discards +@math{O(n)} space! The reason is that when the function discards duplicates, it returns the result of a @scheme[remove-dups] call directly, so the tail-call ``optimization'' kicks in: diff --git a/collects/scribblings/guide/named-let.scrbl b/collects/scribblings/guide/named-let.scrbl index 718bc1874c..a6696979cb 100644 --- a/collects/scribblings/guide/named-let.scrbl +++ b/collects/scribblings/guide/named-let.scrbl @@ -25,9 +25,9 @@ is equivalent to (_proc-id _init-expr ...)) ] -That is, a named @scheme[let] binds a procedure identifier that is -visible only in the procedure's body, and it implicitly calls the -procedure with the values of some initial expressions. +That is, a named @scheme[let] binds a function identifier that is +visible only in the function's body, and it implicitly calls the +function with the values of some initial expressions. @defexamples[ (define (duplicate pos lst) diff --git a/collects/scribblings/guide/simple-syntax.scrbl b/collects/scribblings/guide/simple-syntax.scrbl index 836b32d515..356ca930cf 100644 --- a/collects/scribblings/guide/simple-syntax.scrbl +++ b/collects/scribblings/guide/simple-syntax.scrbl @@ -68,23 +68,23 @@ binds @nonterm{id} to the result of @nonterm{expr}, while @schemeblock[#, @fun-defn-stx] -binds the first @nonterm{id} to a procedure that takes -arguments as named by the remaining @nonterm{id}s. In the -procedure case, the @nonterm{expr}s are the body of the -procedure. When the procedure is called, it returns the result of the -last @nonterm{expr}. +binds the first @nonterm{id} to a function (also called a +@defterm{procedure}) that takes arguments as named by the remaining +@nonterm{id}s. In the function case, the @nonterm{expr}s are the body +of the function. When the function is called, it returns the result of +the last @nonterm{expr}. @defexamples[ (code:line (define five 5) (code:comment #, @t{defines @scheme[five] to be @scheme[5]})) -(code:line (define (piece str) (code:comment #, @t{defines @scheme[piece] as a procedure}) +(code:line (define (piece str) (code:comment #, @t{defines @scheme[piece] as a function}) (substring str 0 five)) (code:comment #, @t{of one argument})) five (piece "hello world") ] -Under the hood, a procedure definition is really the same as a -non-procedure definition, and a procedure name does not have to be -used in a procedure call. A procedure is just another kind of value, +Under the hood, a function definition is really the same as a +non-function definition, and a function name does not have to be +used in a function call. A function is just another kind of value, though the printed form is necessarily less complete than the printed form of a number or string. @@ -93,9 +93,9 @@ piece substring ] -A procedure definition can include multiple expressions for the -procedure's body. In that case, only the value of the last expression -is returned when the procedure is called. The other expressions are +A function definition can include multiple expressions for the +function's body. In that case, only the value of the last expression +is returned when the function is called. The other expressions are evaluated only for some side-effect, such as printing. @defexamples[ @@ -108,7 +108,7 @@ evaluated only for some side-effect, such as printing. Scheme programmers prefer to avoid assignment statements; it's important, though, to understand that multiple expressions are allowed in a definition body, because it explains why the following -@scheme[nogreet] procedure simply returns its argument: +@scheme[nogreet] function simply returns its argument: @def+int[ (define (nogreet name) @@ -118,9 +118,9 @@ in a definition body, because it explains why the following Withing @scheme[nogreet], there are no parentheses around @scheme[string-append "hello " name], so they are three separate -expressions instead of one procedure-call expression. The expressions +expressions instead of one function-call expression. The expressions @scheme[string-append] and @scheme["hello "] are evaluated, but the -results are never used. Instead, the result of the procedure is just +results are never used. Instead, the result of the function is just the result of the expression @scheme[name]. @; ---------------------------------------------------------------------- @@ -145,7 +145,7 @@ support. Re-indenting not only makes the code easier to read, it gives you extra feedback that your parentheses are matched in the way that you intended. For example, if you leave out a closing parenthesis after -the last argument to a procedure, automatic indentation starts the +the last argument to a function, automatic indentation starts the next line under the first argument, instead of under the @scheme[define] keyword: @@ -188,20 +188,20 @@ more examples: ] @;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@section{Procedure Applications} +@section{Function Calls@aux-elem{ (Procedure Applications)}} -We have already seen many procedure calls---or @defterm{procedure -applications} in Scheme termonology. The syntax of a procedure -application is +We have already seen many function calls---or @defterm{procedure +applications} in more traditional Scheme terminology. The syntax of a +function call is @schemeblock[ #, app-expr-stx ] where the number of @nonterm{expr}s determines the number of -arguments supplied to the procedure named by @nonterm{id}. +arguments supplied to the function named by @nonterm{id}. -The @schememodname[big] language pre-defines many procedure +The @schememodname[big] language pre-defines many function identifiers, such as @scheme[substring] and @scheme[string-append]. More examples are below. @@ -257,7 +257,7 @@ the third @nonterm{expr} is evaluated for the result. ] Complex conditionals can be formed by nesting @scheme[if] -expressions. For example, you could make the @scheme[reply] procedure +expressions. For example, you could make the @scheme[reply] function work when given non-strings: @schemeblock[ @@ -269,7 +269,7 @@ work when given non-strings: "huh?")) ] -Instead of duplicating the @scheme["huh?"] case, this procedure is +Instead of duplicating the @scheme["huh?"] case, this function is better written as @schemeblock[ @@ -336,7 +336,7 @@ then the clause's remaining @nonterm{expr}s are ignored, and evaluation continues with the next clause. The last clause can use @scheme[else] as a synonym for a @scheme[#t] test expression. -Using @scheme[cond], the @scheme[reply-more] procedure can be more +Using @scheme[cond], the @scheme[reply-more] function can be more clearly written as follows: @def+int[ @@ -362,11 +362,11 @@ interchangable, as long as @litchar{(} is matched with @litchar{)} and few key places makes Scheme code even more readable. @;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@section{Procedure Applications, Again} +@section{Function Calls, Again} -In our earlier grammar procedure applications, we oversimplified. The -actual syntax of a procedure application allows an arbitrary -expression for the procedure, instead of just an @nonterm{id}: +In our earlier grammar of function calls, we oversimplified. The +actual syntax of a function call allows an arbitrary +expression for the function, instead of just an @nonterm{id}: @schemeblock[ #, app2-expr-stx @@ -374,7 +374,7 @@ expression for the procedure, instead of just an @nonterm{id}: The first @nonterm{expr} is often an @nonterm{id}, such as @scheme[string-append] or @scheme[+], but it can be anything that -evaluates to an procedure. For example, it can be a conditional +evaluates to a function. For example, it can be a conditional expression: @def+int[ @@ -384,18 +384,18 @@ expression: (double 5) ] -Syntactically, the first expression in a procedure application could +Syntactically, the first expression in a function call could even be a number---but that leads to an error, since a number is not a -procedure. +function. @interaction[(1 2 3 4)] -When you accidentally omit a procedure name or when you use +When you accidentally omit a function name or when you use parentheses around an expression, you'll most often get an ``expected a procedure'' error like this one. @;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@section{Anonymous Procedures with @scheme[lambda]} +@section{Anonymous Functions with @scheme[lambda]} Programming in Scheme would be tedious if you had to name all of your numbers. Instead of writing @scheme[(+ 1 2)], you'd have to write @@ -406,10 +406,10 @@ numbers. Instead of writing @scheme[(+ 1 2)], you'd have to write (+ a b) ] -It turns out that having to name all your procedures can be tedious, -too. For example, you might have a procedure @scheme[twice] that takes -a procedure and an argument. Using @scheme[twice] is convenient if you -already have a name for the procedure, such as @scheme[sqrt]: +It turns out that having to name all your functions can be tedious, +too. For example, you might have a function @scheme[twice] that takes +a function and an argument. Using @scheme[twice] is convenient if you +already have a name for the function, such as @scheme[sqrt]: @def+int[ (define (twice f v) @@ -417,7 +417,7 @@ already have a name for the procedure, such as @scheme[sqrt]: (twice sqrt 16) ] -If you want to apply a procedure that is not yet defined, you could +If you want to call a function that is not yet defined, you could define it, and then pass it to @scheme[twice]: @def+int[ @@ -429,15 +429,15 @@ define it, and then pass it to @scheme[twice]: But if the call to @scheme[twice] is the only place where @scheme[louder] is used, it's a shame to have to write a whole definition. In Scheme, you can use a @scheme[lambda] expression to -produce a procedure directly. The @scheme[lambda] form is followed by -identifiers for the procedure's arguments, and then the procedure's +produce a function directly. The @scheme[lambda] form is followed by +identifiers for the function's arguments, and then the function's body expressions: @schemeblock[ #, lambda-expr-stx ] -Evaluating a @scheme[lambda] form by itself produces a procedure: +Evaluating a @scheme[lambda] form by itself produces a function: @interaction[(lambda (s) (string-append s "!"))] @@ -451,8 +451,8 @@ re-written as "hello") ] -Another use of @scheme[lambda] is as a result for a procedure that -generates procedures: +Another use of @scheme[lambda] is as a result for a function that +generates functions: @def+int[ (define (make-add-suffix s2) @@ -463,9 +463,9 @@ generates procedures: ] Scheme is a @defterm{lexically scoped} language, which means that -@scheme[s2] in the procedure returned by @scheme[make-add-suffix] +@scheme[s2] in the function returned by @scheme[make-add-suffix] always refers to the argument for the call that created the -procedure. In other words, the @scheme[lambda]-generated procedure +function. In other words, the @scheme[lambda]-generated function ``remembers'' the right @scheme[s2]: @interaction[ @@ -476,10 +476,10 @@ procedure. In other words, the @scheme[lambda]-generated procedure ] We have so far referred to definitions of the form @scheme[(define #, -@nonterm{id} #, @nonterm{expr})] as ``non-procedure +@nonterm{id} #, @nonterm{expr})] as ``non-function definitions.'' This characterization is misleading, because the @nonterm{expr} could be a @scheme[lambda] form, in which case -the definition is equivalent to using the ``procedure'' definition +the definition is equivalent to using the ``function'' definition form. For example, the following two definitions of @scheme[louder] are equivalent: @@ -494,7 +494,7 @@ louder ] Note that the expression for @scheme[louder] in the second case is an -``anonymous'' procedure written with @scheme[lambda], but, if +``anonymous'' function written with @scheme[lambda], but, if possible, the compiler infers a name, anyway, to make printing and error reporting as informative as possible. @@ -503,7 +503,7 @@ error reporting as informative as possible. @scheme[define], @scheme[let], and @scheme[let*]} It's time to retract another simplification in our grammar of -Scheme. In the body of a procedure, definitions can appear before the +Scheme. In the body of a function, definitions can appear before the body expressions: @schemeblock[ @@ -511,8 +511,8 @@ body expressions: #, lambda2-expr-stx ] -Definitions at the start of a procedure body are local to the -procedure body. +Definitions at the start of a function body are local to the +function body. @defexamples[ (define (converse s) diff --git a/collects/scribblings/guide/truth.scrbl b/collects/scribblings/guide/truth.scrbl index f9c30e160e..b9d2d2302e 100644 --- a/collects/scribblings/guide/truth.scrbl +++ b/collects/scribblings/guide/truth.scrbl @@ -7,7 +7,7 @@ @title{Pairs, Lists, and Scheme Syntax} -The @scheme[cons] procedure actually accepts any two values, not just +The @scheme[cons] function actually accepts any two values, not just a list for the second argument. When the second argument is not @scheme[empty] and not itself produced by @scheme[cons], the result prints in a special way. The two values joined with @scheme[cons] are printed @@ -18,7 +18,7 @@ whitespace) in between: Thus, a value produced by @scheme[cons] is not always a list. In general, the result of @scheme[cons] is a @defterm{pair}. The more -traditional name for the @scheme[cons?] procedure is @scheme[pair?], +traditional name for the @scheme[cons?] function is @scheme[pair?], and we'll use the traditional name from now on. The name @scheme[rest] also makes less sense for non-list pairs; the @@ -48,7 +48,7 @@ mistake, such as accidentally reversing the arguments to @interaction[(cons (list 2 3) 1) (cons 1 (list 2 3))] Non-list pairs are used intentionally, sometimes. For example, the -@scheme[make-immutable-hash-table] procedure takes a list of pairs, +@scheme[make-immutable-hash-table] function takes a list of pairs, where the @scheme[car] of each pair is a key and the @scheme[cdr] is an arbitrary value. @@ -119,7 +119,7 @@ to be made up of the same letters. Indeed, the intrinsic value of a symbol is nothing more than its character content. In this sense, symbols and strings are almost the -same thing, and the main difference is how they print. The procedures +same thing, and the main difference is how they print. The functions @scheme[symbol->string] and @scheme[string->symbol] convert between them. diff --git a/collects/scribblings/guide/welcome.scrbl b/collects/scribblings/guide/welcome.scrbl index b7e2be7537..abb50ca827 100644 --- a/collects/scribblings/guide/welcome.scrbl +++ b/collects/scribblings/guide/welcome.scrbl @@ -80,10 +80,10 @@ written with double quotes at the start and end of the string: @interaction["hello world"] Scheme uses parentheses to wrap larger expressions---almost any kind -of expression, other than simple constants. For example, a procedure -call is written: open parenthesis, procedure name, argument +of expression, other than simple constants. For example, a function +call is written: open parenthesis, function name, argument expression, and closing parenthesis. The following expression calls -the built-in procedure @scheme[substring] with the arguments +the built-in function @scheme[substring] with the arguments @scheme["hello world"], @scheme[0], and @scheme[5]: @interaction[(substring "hello world" 0 5)] @@ -91,7 +91,7 @@ the built-in procedure @scheme[substring] with the arguments @; ---------------------------------------------------------------------- @section{Definitions and Interactions} -You can define your own procedures that work like @scheme[subtring] by +You can define your own functions that work like @scheme[subtring] by using the @scheme[define] form, like this: @def+int[ @@ -131,7 +131,7 @@ sequence: (piece "howdy universe") ] -The @scheme[enter!] procedure both loads the code and switches the +The @scheme[enter!] function both loads the code and switches the evaluation context to the inside of the module, just like DrScheme's @onscreen{Run} button. diff --git a/collects/scribblings/new-lambda.ss b/collects/scribblings/new-lambda.ss index 7345c49f87..4dcc82aa29 100644 --- a/collects/scribblings/new-lambda.ss +++ b/collects/scribblings/new-lambda.ss @@ -1,5 +1,6 @@ (module new-lambda mzscheme - (require-for-syntax (lib "name.ss" "syntax")) + (require-for-syntax (lib "name.ss" "syntax") + (lib "define.ss" "syntax")) (provide (all-from-except mzscheme #%datum lambda define #%app) (rename new-datum #%datum) @@ -203,7 +204,7 @@ (begin (when needs-default? (raise-syntax-error - #f "default value missing" stx (syntax id))) + #f "default-value expression missing" stx (syntax id))) (with-syntax ([(plain opt-ids opts kws need-kw rest) (loop #'rest #f)]) #'((id . plain) opt-ids ([id #f #:plain] . opts) kws need-kw rest)))] [([id default] . rest) @@ -386,7 +387,6 @@ 'kws))))]))))))])) (define (missing-kw proc . args) - (printf "~s\n" args) (apply (keyword-procedure-extract null 0 proc) null @@ -522,17 +522,11 @@ ;; ---------------------------------------- ;; `define' with keyword arguments - ;; Not enough syntax checking here, yet. - ;; Also, the currying notation needs to be - ;; supported. - (define-syntax (new-define stx) - (syntax-case stx () - [(_ (id . formals) . body) - (identifier? #'id) - (syntax/loc stx (define id (new-lambda formals . body)))] - [(_ . rest) - (syntax/loc stx (define . rest))])) + (let-values ([(id rhs) + (normalize-definition stx #'new-lambda #t #t)]) + (quasisyntax/loc stx + (define #,id #,rhs)))) ;; ---------------------------------------- ;; `#%app' with keyword arguments @@ -657,14 +651,18 @@ (check-kw-args p kws) (values #f (car kws)))]) (let ([args-str - ;; Hack to format arguments: - (with-handlers ([exn:fail? - (lambda (exn) - (cadr (regexp-match #rx"other arguments were: (.*)$" - (exn-message exn))))]) - (apply raise-type-error 'x "x" 0 'x - (append (apply append (map list kws kw-args)) - args)))]) + (if (null? args) + "no arguments supplied" + ;; Hack to format arguments: + (with-handlers ([exn:fail? + (lambda (exn) + (format "arguments were: ~a" + (cadr (regexp-match + #rx"other arguments were: (.*)$" + (exn-message exn)))))]) + (apply raise-type-error 'x "x" 0 'x + (append (apply append (map list kws kw-args)) + args))))]) (raise (make-exn:fail:contract (if extra-kw @@ -672,28 +670,28 @@ (format (string-append "procedure application: procedure: ~e;" - " does not expect an argument with keyword ~a; arguments were: ~a") + " does not expect an argument with keyword ~a; ~a") p extra-kw args-str) (format (string-append "procedure application: expected a procedure that" - " accepts keyword arguments, given ~e; arguments were: ~a") + " accepts keyword arguments, given ~e; ~a") p args-str)) (if missing-kw (format (string-append "procedure application: procedure: ~e; requires" - " an argument with keyword ~a, not supplied; arguments were: ~a") + " an argument with keyword ~a, not supplied; ~a") p missing-kw args-str) (format (string-append "procedure application: no case matching ~a non-keyword" - " arguments for: ~e; arguments were: ~a") + " arguments for: ~e; ~a") (- n 2) p args-str))) diff --git a/collects/scribblings/quick/quick.scrbl b/collects/scribblings/quick/quick.scrbl index 2b7a61913f..a82d36f93a 100644 --- a/collects/scribblings/quick/quick.scrbl +++ b/collects/scribblings/quick/quick.scrbl @@ -57,17 +57,17 @@ string @scheme["art gallery"]: @mr-interaction[5 "art gallery"] -An expression can also be a procedure call. To call a procedure, put -an open parenthesis before the procedure name, then expressions for the -procedure arguments, and then a close parenthesis, like this: +An expression can also be a function call. To call a function, put +an open parenthesis before the function name, then expressions for the +function arguments, and then a close parenthesis, like this: @mr-interaction[(circle 10)] -A result from the @scheme[circle] procedure is a picture value, which +A result from the @scheme[circle] function is a picture value, which prints as an expression result in much the same way that numbers or strings print. The argument to @scheme[circle] determines the circle's size in pixels. As you might guess, there's a -@scheme[rectangle] procedure that takes two arguments instead of one: +@scheme[rectangle] function that takes two arguments instead of one: @mr-interaction[(rectangle 10 20)] @@ -79,14 +79,14 @@ what happens: Note that DrScheme highlights the source of the error in pink. In addition to basic picture constructors like @scheme[circle] and -@scheme[rectangle], there's a @scheme[hc-append] procedure that -combines pictures. When you start composing procedure calls in Scheme, +@scheme[rectangle], there's a @scheme[hc-append] function that +combines pictures. When you start composing function calls in Scheme, it looks like this: @mr-interaction[(hc-append (circle 10) (rectangle 10 20))] The hyphen in the name @scheme[hc-append] is just a part of the -identifier; it's not @scheme[hc] minus @scheme[append]. The procedure +identifier; it's not @scheme[hc] minus @scheme[append]. The function name starts with @scheme[h] because it combines pictures horizontally, and the next letter is @scheme[c] because the pictures are centered vertically. If you wonder what other functions exist (perhaps a way to @@ -126,10 +126,10 @@ area. In practice, though, the definitions area is where your program lives---it's the file that you save---while the interaction area is for transient explorations and debugging tasks. -Let's add a procedure definition to the program. A procedure +Let's add a function definition to the program. A function definition uses @scheme[define], just like our shape definitions, but with -an open parenthesis before the procedure name, and names for the -procedure arguments before the matching close parenthesis: +an open parenthesis before the function name, and names for the +function arguments before the matching close parenthesis: @mr-schemeblock+eval[ (define (square n) @@ -138,7 +138,7 @@ procedure arguments before the matching close parenthesis: (filled-rectangle n n)) ] -The syntax of the definition mirrors the syntax of a procedure +The syntax of the definition mirrors the syntax of a function call: @mr-interaction[(square 10)] @@ -156,7 +156,7 @@ definition area. @section{Local Binding} The @scheme[define] form can be used in some places to create local -bindings. For example, it can be used inside a procedure body: +bindings. For example, it can be used inside a function body: @mr-def+int[ (define (four p) @@ -194,21 +194,22 @@ contrast, allows later bindings to use earlier bindings: ] @; ---------------------------------------------------------------------- -@section{Procedures are Values} +@section{Functions are Values} -Instead of calling @scheme[circle] as a procedure, try evaluating just +Instead of calling @scheme[circle] as a function, try evaluating just @scheme[circle] as an expression: @mr-interaction[circle] -That is, the identifier @scheme[circle] is bound to a procedure, just -like @scheme[c] is bound to a circle. Unlike a cicrle picture, there's -not a simple way of completely printing the procedure, so DrScheme just -prints @procedure{circle}. +That is, the identifier @scheme[circle] is bound to a function +(a.k.a. ``procedure''), just like @scheme[c] is bound to a +circle. Unlike a cicrle picture, there's not a simple way of +completely printing the function, so DrScheme just prints +@procedure{circle}. -This example shows that procedures are values, just like numbers and -pictures (even if they don't print as nicely). Since procedures are -values, you can define procedures that expect other procedures as +This example shows that functions are values, just like numbers and +pictures (even if they don't print as nicely). Since functions are +values, you can define functions that expect other functions as arguments: @mr-def+int[ @@ -218,21 +219,21 @@ arguments: (series square) ] -When calling a procedure that accepts a procedure argument, the -argument procedure often isn't needed anywhere else. Having to write +When calling a function that accepts a function argument, the +argument function often isn't needed anywhere else. Having to write down the function via @scheme[define] would be a hassle, because you -have to make up a name and find a place to put the procedure +have to make up a name and find a place to put the function definition. The alternative is to use @scheme[lambda], which creates an -anonymous procedure: +anonymous function: @mr-interaction[(series (lambda (size) (checkerboard (square size))))] The parenthesized names after a @scheme[lambda] are the arguments to -the procedure, and the expression after the argument names is the -procedure body. Using the word ``lambda'' instead of ``function'' or +the function, and the expression after the argument names is the +function body. Using the word ``lambda'' instead of ``function'' or ``procedure'' is part of Scheme's history and culture. -A procedure-form @scheme[define] is really a shorthand for a simple +A function @scheme[define] is really a shorthand for a simple @scheme[define] using @scheme[lambda] as the value. For example, the @scheme[series] definition could be written as @@ -242,7 +243,7 @@ A procedure-form @scheme[define] is really a shorthand for a simple (hc-append 4 (mk 5) (mk 10) (mk 20)))) ] -Most Schemers prefer to use the shorthand procedure form with +Most Schemers prefer to use the shorthand function form with @scheme[define] instead of expanding to @scheme[lambda]. @; ---------------------------------------------------------------------- @@ -254,7 +255,7 @@ environment of the expression determines the identifier's binding. This rule applies to identifiers in a @scheme[lambda] body as well as anywhere else. -For example, in the following @scheme[color-series] procedure the uses +For example, in the following @scheme[color-series] function the uses of @scheme[mk] in each @scheme[lambda] form to refer to the argument of @scheme[color-series], since that's the binding that is textually in scope: @@ -269,8 +270,8 @@ scope: (rgb-series square) ] -Here's another example, where @scheme[rgb-maker] takes a procedure and -returns a new one that remembers and uses the original procedure. +Here's another example, where @scheme[rgb-maker] takes a function and +returns a new one that remembers and uses the original function. @mr-def+int[ (define (rgb-maker mk) @@ -282,7 +283,7 @@ returns a new one that remembers and uses the original procedure. (series (rgb-maker square)) ] -Note how composing procedures via @scheme[rgb-maker] creates a +Note how composing functions via @scheme[rgb-maker] creates a different alignment of objects within the picture compared to using @scheme[rgb-series]. @@ -293,7 +294,7 @@ Scheme inherits much of its style from the langauge Lisp, whose name originally stood for ``LISt Processor,'' and lists remain an important part of Scheme. -The @scheme[list] procedure takes any number of arguments and returns +The @scheme[list] function takes any number of arguments and returns a list containing the given values: @mr-interaction[(list "red" "green" "blue") @@ -310,9 +311,9 @@ documentation and in DrScheme, result parentheses are printed in blue, unlike expression parentheses. If you have a list, then you'll eventually want to do something with -each of the elements. The @scheme[map] procedure takes a list and a -procedure to apply to each element of the list; it returns a new list -to combine the procedure's results: +each of the elements. The @scheme[map] function takes a list and a +function to apply to each element of the list; it returns a new list +to combine the function's results: @mr-def+int[ (define (rainbow p) @@ -322,8 +323,8 @@ to combine the procedure's results: (rainbow (square 5)) ] -Another procedure that works with lists is @scheme[apply]. Like -@scheme[map], it takes a procedure and a list, but a procedure given +Another function that works with lists is @scheme[apply]. Like +@scheme[map], it takes a function and a list, but a function given to @scheme[apply] should take all of the arguments at once, instead of each one individually. The @scheme[apply] function is especially useful with functions that take any number of arguments, such as @@ -336,8 +337,8 @@ useful with functions that take any number of arguments, such as Note that @scheme[(vc-append (rainbow (square 5)))] would not work, because @scheme[vc-append] does not want a list as an argument; it wants a picture as an argument, and it is willing to accept any number -of them. The @scheme[apply] procedure bridges the gap between a -procedure that wants many arguments and a list of those arguments as a +of them. The @scheme[apply] function bridges the gap between a +function that wants many arguments and a list of those arguments as a single value. @; ---------------------------------------------------------------------- @@ -350,12 +351,12 @@ Since your program in the definitions window starts with all of the code that you put in the definitions window is inside a module. Furthermore, the module intially imports everything from the module designated by @schememodname[slideshow], which exports -picture-making procedures as well as more commonly used procedures +picture-making functions as well as more commonly used functions such as @scheme[list] and @scheme[map]. To import additional libraries, use the @scheme[require] form. For example, the library @scheme[(lib "flash.ss" "texpict")] provides a -@scheme[filled-flash] procedure: +@scheme[filled-flash] function: @mr-def+int[ (require (lib "flash.ss" "texpict")) @@ -408,8 +409,8 @@ Modules are named and distributed in various ways: and when you run this later program, a rainbow list of squares is the output. Note that @file{use.ss} is written using the initial import @schememodname[little], which does not - supply any picture-making procedures itself---but does provide - @scheme[require] and the procedure-calling syntax.} + supply any picture-making functions itself---but does provide + @scheme[require] and the function-calling syntax.} ] @@ -433,15 +434,15 @@ Here's another library to try: Instead of a circle, the result is a picture of the code that, if it were used as an expression, would produce a circle. In other words, -@scheme[code] is not a procedure, but instead a new syntactic form for +@scheme[code] is not a function, but instead a new syntactic form for creating pictures; the bit between the opening parenthesese with @scheme[code] is not an expression, but instead manipulated by the @scheme[code] syntactic form. This helps explain what we meant in the previous section when we said that @schememodname[little] provides @scheme[require] and the -procedure-calling syntax. Libraries are not restricted to exporting -values, such as procedures; they can also define new syntax. In this +function-calling syntax. Libraries are not restricted to exporting +values, such as functions; they can also define new syntax. In this sense, Scheme isn't exactly language at all; it's more of an idea for how to structure a language so that you can extend it or create entirely new languages. @@ -487,7 +488,7 @@ take you a long way! An object system is another example of a sophisticated language extension that is worth learning and using for a Scheme users. Objects -are sometimes better than procedures, even when you have +are sometimes better than functions, even when you have @scheme[lambda], and objects work especially well for graphical user interfaces. The API for Scheme's GUI and graphics system is expressed in terms of objects and classes. @@ -518,8 +519,8 @@ argument @scheme[#t] in this case is the boolean constant ``true.'' Pictures generated with @schememodname[slideshow] encapsulate a function that uses MrEd's drawing commands to render the picture to a drawing context, such as a canvas in a frame. The -@scheme[make-pict-drawer] procedure from @schememodname[slideshow] -exposes a picture's drawing procedure. We can use +@scheme[make-pict-drawer] function from @schememodname[slideshow] +exposes a picture's drawing function. We can use @scheme[make-pict-drawer] in a canvas-painting callback to draw a picture into a canvas: @@ -550,7 +551,7 @@ is really just a @scheme[lambda] in disguise. While those are all part of PLT Scheme, they are not the main ingredients of day-to-day programming in PLT Scheme. -Instead, PLT Scheme programmers typically program with procedures, +Instead, PLT Scheme programmers typically program with functions, records, objects, exceptions, regular expressions, modules, and threads. That is, instead of a ``minimalist'' language---which is the way that Scheme is often described---PLT Scheme offers a rich language diff --git a/collects/scribblings/reference/syntax.scrbl b/collects/scribblings/reference/syntax.scrbl index d4469c764b..f359117ac7 100644 --- a/collects/scribblings/reference/syntax.scrbl +++ b/collects/scribblings/reference/syntax.scrbl @@ -394,3 +394,6 @@ and in the @scheme[body]s. @;------------------------------------------------------------------------ @section{Sequencing: @scheme[begin]} +@;------------------------------------------------------------------------ +@section[#:tag "mz:define"]{Definitions: @scheme[define] and @scheme[define-values]} + diff --git a/collects/scribblings/scribble/basic.scrbl b/collects/scribblings/scribble/basic.scrbl index 2dcb54392b..ac4c86063e 100644 --- a/collects/scribblings/scribble/basic.scrbl +++ b/collects/scribblings/scribble/basic.scrbl @@ -93,6 +93,9 @@ have Scribble's @file{scheme.ss} and @file{manual.ss}). @scheme[decode-content], and wraps the result as an element with style @scheme[#f].} +@def-elem-proc[aux-elem]{Like @scheme[elem], but creates an +@scheme[aux-element].} + @def-style-proc[italic] @def-style-proc[bold] @def-style-proc[tt] diff --git a/collects/scribblings/scribble/manual.scrbl b/collects/scribblings/scribble/manual.scrbl index cf90c5ee78..16d791dd5c 100644 --- a/collects/scribblings/scribble/manual.scrbl +++ b/collects/scribblings/scribble/manual.scrbl @@ -293,10 +293,11 @@ as a file name (e.g., in typewriter font and in in quotes).} as a command line (e.g., in typewriter font).} @; ------------------------------------------------------------------------ -@section{Section Links} +@section[#:tag "scribble:manual:section-links"]{Section Links} @defproc[(secref [tag string?]) element?]{Inserts the hyperlinked -title of the section tagged @scheme[tag].} +title of the section tagged @scheme[tag], but @scheme{aux-element} +items in the title content are omitted in the hyperlink label.} @defproc[(seclink [tag string?] [pre-content any/c] ...) element?]{The content from @scheme[pre-content] is hyperlinked to the section tagged @scheme[tag].} @@ -305,7 +306,6 @@ title of the section tagged @scheme[tag].} @scheme[pre-content] is hyperlinked to the definition of @scheme[id].} - @; ------------------------------------------------------------------------ @section{Indexing} diff --git a/collects/scribblings/scribble/struct.scrbl b/collects/scribblings/scribble/struct.scrbl index 8b6b868357..a2789f3b15 100644 --- a/collects/scribblings/scribble/struct.scrbl +++ b/collects/scribblings/scribble/struct.scrbl @@ -194,6 +194,14 @@ section, and the last argument correspond to global information } +@defstruct[(aux-element element) ()]{ + +Instances of this structure type are intended for use in titles, where +the auxiliary part of the title can be omitted in hyperlinks. See, for +example, @scheme[secref]. + +} + @defstruct[delayed-element ([render (any/c part? any/c . -> . list?)])]{ The @scheme[render] procedure's arguments are the same as for diff --git a/collects/syntax/define.ss b/collects/syntax/define.ss index abc4a4d08a..320483cc5a 100644 --- a/collects/syntax/define.ss +++ b/collects/syntax/define.ss @@ -4,11 +4,9 @@ (provide normalize-definition) - ;; This code was shamefully copied from MzScheme's startup.ss! - (define normalize-definition (case-lambda - [(stx lambda-stx check-context?) + [(stx lambda-stx check-context? allow-key+opt?) (when (and check-context? (memq (syntax-local-context) '(expression))) (raise-syntax-error @@ -45,35 +43,91 @@ ;; a proc maker instead of a final proc to enable ;; left-to-right checking of the function protos (lambda (proto) - (let-values ([(args mk-rhs) + (let-values ([(args rests mk-rhs) (syntax-case proto () [(id arg ...) (values (syntax->list #'(arg ...)) + null (lambda (body) (quasisyntax/loc stx (#,lambda-stx (arg ...) . #,body))))] [(id arg ... . rest) - (values (syntax->list #'(arg ... rest)) + (values (syntax->list #'(arg ...)) + (list #'rest) (lambda (body) (quasisyntax/loc stx (#,lambda-stx (arg ... . rest) . #,body))))])]) - (for-each (lambda (a) - (unless (identifier? a) - (raise-syntax-error - #f - "not an identifier for procedure argument" - stx - a))) - args) - (let ([dup (check-duplicate-identifier args)]) - (when dup - (raise-syntax-error - #f - "duplicate argument identifier" - stx - dup))) - mk-rhs))] + (let* ([args (if allow-key+opt? + (let* ([kw-ht (make-hash-table)] + [check-kw + (lambda (kw) + (when (hash-table-get kw-ht (syntax-e kw) #f) + (raise-syntax-error + #f + "duplicate keyword for argument" + stx + kw)) + (hash-table-put! kw-ht (syntax-e kw) #t))]) + (let loop ([args args][need-def? #f]) + (syntax-case args () + [() null] + [(id . more) + (identifier? #'id) + (if need-def? + (raise-syntax-error + #f + "default-value expression missing" + stx + #'id) + (cons #'id (loop #'more #f)))] + [([id def-expr] . more) + (identifier? #'id) + (cons #'id (loop #'more #t))] + [(kw id . more) + (and (keyword? (syntax-e #'kw)) + (identifier? #'id)) + (begin + (check-kw #'kw) + (cons #'id (loop #'more #t)))] + [(kw [id def-expr] . more) + (and (keyword? (syntax-e #'kw)) + (identifier? #'id)) + (begin + (check-kw #'kw) + (cons #'id (loop #'more #t)))] + [(kw . more) + (keyword? (syntax-e #'kw)) + (raise-syntax-error #f + "missing argument identifier after keyword" + stx + #'kw)] + [(x . more) + (raise-syntax-error + #f + "not an identifier, identifier with default, or keyword for procedure argument" + stx + #'x)]))) + args)] + [all-args (if (null? rests) + args + (append args rests))]) + (for-each (lambda (a) + (unless (identifier? a) + (raise-syntax-error + #f + "not an identifier for procedure argument" + stx + a))) + all-args) + (let ([dup (check-duplicate-identifier all-args)]) + (when dup + (raise-syntax-error + #f + "duplicate argument identifier" + stx + dup))) + mk-rhs)))] [general-proto ;; proto is guaranteed to be a stx-pair (lambda (proto) @@ -106,4 +160,5 @@ "bad syntax (no expressions for procedure body)" stx)) (values id (mk-rhs #'body)))])] - [(stx lambda-stx) (normalize-definition stx lambda-stx #t)]))) + [(stx lambda-stx check-context?) (normalize-definition stx lambda-stx check-context? #f)] + [(stx lambda-stx) (normalize-definition stx lambda-stx #t #f)]))) diff --git a/collects/syntax/doc.txt b/collects/syntax/doc.txt index a694ed8a5e..0dc88b2097 100644 --- a/collects/syntax/doc.txt +++ b/collects/syntax/doc.txt @@ -114,9 +114,9 @@ _toplevel.ss_: helper for moduleless compilation and expansion _define.ss_: handling all the same function forms as `define' ====================================================================== -> (normalize-definition defn-stx lambda-id-stx [check-context?]) - +> (normalize-definition defn-stx lambda-id-stx [check-context? opt+kws?]) - takes a definition form whose shape is like `define' (though - possibly with a different keyword) and returns two values: the + possibly with a different name) and returns two values: the defined identifier and the right-hand side expression. To generate the right-hand side, this function may need to insert @@ -128,6 +128,10 @@ _define.ss_: handling all the same function forms as `define' `(syntax-local-context)' indicates that the current context is an expression context. The default value of `check-context?' is #t. + If `opt-kws?' is #t, then arguments of the form `[id expr]', + `keyword id', and `keyword [id expr]' are allowed, and they are + preserved in the expansion. + ====================================================================== _struct.ss_: generating the same names as `define-struct' ======================================================================