diff --git a/collects/mzscheme/mzscheme.scrbl b/collects/mzscheme/mzscheme.scrbl index 5109de2f2b..d36f459bd4 100644 --- a/collects/mzscheme/mzscheme.scrbl +++ b/collects/mzscheme/mzscheme.scrbl @@ -3,34 +3,47 @@ (for-label mzscheme (only-in r5rs set-car! set-cdr!) (only-in scheme/base + for-syntax #%plain-module-begin exact-nonnegative-integer? exact-positive-integer? syntax? #%plain-lambda #%plain-app - syntax->datum datum->syntax))) + syntax->datum datum->syntax + make-base-empty-namespace))) -@(define-syntax-rule (def-base base-define +@(define-syntax-rule (def-base base-define base-define-struct + base-if base-cond base-case base-top-interaction + base-open-input-file base-free-identifier=? base-free-template-identifier=? base-free-transformer-identifier=? base-free-label-identifier=?) (begin (require (for-label scheme/base)) (define base-define (scheme define)) - (define base-free-identifier=? (scheme base-free-identifier=?)) - (define base-free-template-identifier=? (scheme base-free-template-identifier=?)) - (define base-free-transformer-identifier=? (scheme base-free-transformer-identifier=?)) - (define base-free-label-identifier=? (scheme base-free-label-identifier=?)))) -@(def-base base-define + (define base-define-struct (scheme define-struct)) + (define base-if (scheme if)) + (define base-cond (scheme cond)) + (define base-case (scheme case)) + (define base-top-interaction (scheme #%top-interaction)) + (define base-open-input-file (scheme open-input-file)) + (define base-free-identifier=? (scheme free-identifier=?)) + (define base-free-template-identifier=? (scheme free-template-identifier=?)) + (define base-free-transformer-identifier=? (scheme free-transformer-identifier=?)) + (define base-free-label-identifier=? (scheme free-label-identifier=?)))) +@(def-base base-define base-define-struct + base-if base-cond base-case base-top-interaction + base-open-input-file base-free-identifier=? base-free-template-identifier=? base-free-transformer-identifier=? base-free-label-identifier=?) +@(define old-vers @elem{version 372}) @title{@bold{MzScheme}: Legacy Module Language} @defmodule[mzscheme]{ The @schememodname[mzscheme] language provides nearly the same -bindings as the @schememodname[mzscheme] module of PLT Scheme version -372 and earlier.} +bindings as the @schememodname[mzscheme] module of PLT Scheme +@|old-vers| and earlier.} Unlike old version, the @schememodname[mzscheme] language does not include @scheme[set-car!] or @scheme[set-cdr!], and @scheme[cons] @@ -38,8 +51,8 @@ makes immutable pairs, as in @scheme[scheme/base]; those changes make modules built on @schememodname[mzscheme] reasonably compatible with modules built on @schememodname[scheme/base]. -Otherwise, the @schememodname[mzscheme] language provides some -functions in @schememodname[scheme/base] under old names, such as +Otherwise, the @schememodname[mzscheme] language shares many bindings +with @schememodname[scheme/base]. It renames a few bindings, such as @scheme[syntax-object->datum] instead of @scheme[syntax->datum], and it provides old versions of some syntactic forms, such as @scheme[lambda] without support for keyword and optional arguments. @@ -50,16 +63,49 @@ it provides old versions of some syntactic forms, such as @section{Old Syntactic Forms} -@defform[(lambda formals body ...+)]{ +@defform[(#%module-begin form ...)]{ -The same as @scheme[#%plain-lambda].} +Like @scheme[#%plain-module-begin] from @schememodname[scheme/base], +but @scheme[(require-for-syntax mzscheme)] is added to the beginning +of the @scheme[form] sequence, thus importing @schememodname[mzscheme] +into the transformer environment for the module body. (In contrast, +@schememodname[scheme/base] exports @scheme[for-syntax] minimal +transformer support, while @schememodname[scheme] exports all of +@schememodname[scheme/base] @scheme[for-syntax].} + + +@defform[(#%plain-module-begin form ...)]{ + +The same binding as @scheme[#%plain-module-begin] from +@schememodname[scheme/base].} + + +@defform[(#%plain-lambda formals body ...+)]{ + +The same binding as @scheme[#%plain-lambda] in +@schememodname[scheme/base]. (This binding was not present in +@|old-vers| and earlier.)} + + +@deftogether[( +@defform[(lambda formals body ...+)] +@defform[(λ formals body ...+)] +)]{ + +The same bindings as @scheme[#%plain-lambda].} @defform*[[(#%app proc-expr arg-expr ...) (#%app)]]{ -The same as @scheme[#%plain-app].} +The same binding as @scheme[#%plain-app] from +@schememodname[scheme/base].} +@defform*[[(#%plain-app proc-expr arg-expr ...) + (#%plain-app)]]{ + +The same binding as @scheme[#%app]. (This binding was not present in +@|old-vers| and earlier.)} @defform*/subs[[(define id expr) (define (head args) body ...+)] @@ -71,14 +117,124 @@ The same as @scheme[#%plain-app].} Like @|base-define| in @schememodname[scheme/base], but without support for keyword arguments or optional arguments.} +@defform*[[(if test-expr then-expr else-expr) + (if test-expr then-expr)]]{ + +Like @|base-if| in @schememodname[scheme/base], but @scheme[else-expr] +defaults to @scheme[(void)].} + +@deftogether[( +@defform[(cond cond-clause ...)] +@defform[(case val-expr case-clause ...)] +)]{ + +Like @|base-cond| and @|base-case| in @schememodname[scheme/base], but +@scheme[else] and @scheme[=>] are recognized as unbound identifiers, +instead of as the @schememodname[scheme/base] bindings. } + +@defform[(fluid-let ([id expr] ...) body ...+)]{ + +Provides a kind of dynamic binding via mutation of the @scheme[id]s. + +The @scheme[fluid-let] form first evaluates each @scheme[expr] to +obtain an @defterm{entry value} for each @scheme[id]. As evaluation +moves into @scheme[body], either though normal evaluation or a +continuation jump, the current value of each @scheme[id] is swapped +with the entry value. On exit from @scheme[body], then the current +value and entry value are swapped again.} + +@defform/subs[(define-struct id-maybe-super (field-id ...) maybe-inspector-expr) + ([maybe-inspector-expr code:blank + expr])]{ + +Like @base-define-struct from @scheme[scheme/base], but with fewer +options. Each field is implicitly mutable, and the optional +@scheme[expr] is analogous to supplying an @scheme[#:inspector] +expression.} + +@defform[(let-struct id-maybe-super (field-id ...) body ...+)]{ + +Expands to + +@schemeblock[ +(let () + (define-struct id-maybe-super (field-id ...)) + body ...+) +]} + +@deftogether[( +@defform[(require raw-require-spec)] +@defform[(require-for-syntax raw-require-spec)] +@defform[(require-for-template raw-require-spec)] +@defform[(require-for-label raw-require-spec)] +@defform[(provide raw-provide-spec)] +@defform[(provide-for-syntax raw-provide-spec)] +@defform[(provide-for-label raw-provide-spec)] +)]{ + +Like @scheme[#%require] and @scheme[#%provide]. The +@schemeidfont{-for-syntax}, @schemeidfont{-for-template}, and +@schemeidfont{-for-label} forms are translated to @scheme[#%require] +and @scheme[#%provide] using @schemeidfont{for-syntax}, +@schemeidfont{for-template}, and @schemeidfont{for-label} sub-forms, +respectively.} + +@defform[(#%datum . datum)]{ + +Expands to @scheme[(quote datum)], even if @scheme[datum] is a +keyword.} + +@defform[(#%top-interaction . form)]{ + +The same as @|base-top-interaction| in @schememodname[scheme/base].} + @; ---------------------------------------- @section{Old Functions} -@defproc[(syntax-object->datum [stx syntax?]) any]{ +@deftogether[( +@defproc[(open-input-file [file path-string?] [mode (one-of/c 'text 'binary) 'binary]) + input-port?] +@defproc[(open-output-file [file path-string?] + [mode (one-of/c 'text 'binary) 'binary] + [exists (one-of/c 'error 'append 'update + 'replace 'truncate 'truncate/replace) 'error]) + input-port?] +@defproc[(open-input-output-file [file path-string?] + [mode (one-of/c 'text 'binary) 'binary] + [exists (one-of/c 'error 'append 'update + 'replace 'truncate 'truncate/replace) 'error]) + (values input-port? output-port?)] +@defproc[(with-input-from-file [file path-string?] + [thunk (-> any)] + [mode (one-of/c 'text 'binary) 'binary]) + any] +@defproc[(with-output-to-file [file path-string?] + [thunk (-> any)] + [mode (one-of/c 'text 'binary) 'binary] + [exists (one-of/c 'error 'append 'update + 'replace 'truncate 'truncate/replace) 'error]) + any] +@defproc[(call-with-input-file [file path-string?] + [proc (input-port? -> any)] + [mode (one-of/c 'text 'binary) 'binary]) + any] +@defproc[(call-with-output-file [file path-string?] + [proc (output-port? -> any)] + [mode (one-of/c 'text 'binary) 'binary] + [exists (one-of/c 'error 'append 'update + 'replace 'truncate 'truncate/replace) 'error]) + any] +)]{ -The same as @scheme[syntax->datum].} +Like @base-open-input-file, etc. from @schememodname[scheme/base], but +@scheme[mode] and @scheme[exists] arguments are not keyword +arguments. When both @scheme[mode] and @scheme[exists] are accepted, +they are accepted in either order.} + +@deftogether[( +@defproc[(syntax-object->datum [stx syntax?]) any] @defproc[(datum->syntax-object [ctxt (or/c syntax? false/c)] [v any/c] [srcloc (or/c syntax? false/c @@ -89,25 +245,47 @@ The same as @scheme[syntax->datum].} (or/c exact-positive-integer? false/c)))] [prop (or/c syntax? false/c) #f] [cert (or/c syntax? false/c) #f]) - syntax?]{ + syntax?] +)]{ -The same as @scheme[datum->syntax].} +The same as @scheme[syntax->datum] and @scheme[datum->syntax].} + +@deftogether[( +@defproc[(module-identifier=? [a-id syntax?][b-id syntax?]) boolean?] +@defproc[(module-transformer-identifier=? [a-id syntax?][b-id syntax?]) boolean?] +@defproc[(module-template-identifier=? [a-id syntax?][b-id syntax?]) boolean?] +@defproc[(module-label-identifier=? [a-id syntax?][b-id syntax?]) boolean?] +@defproc[(free-identifier=? [a-id syntax?][b-id syntax?]) boolean?] +)]{ + +The @scheme[module-identifier=?], @|etc| functions are the same as +@base-free-identifier=?, @|etc| in @schememodname[scheme/base]. + +The @scheme[free-identifier=?] procedure returns + +@schemeblock[ +(and (eq? (syntax-e a) (syntax-e b)) + (module-identifier=? a b)) +]} -@defproc[(module-identifier=? [a-id syntax?][b-id syntax?]) boolean?]{ +@defproc[(make-namespace [mode (one-of/c 'initial 'empty) 'initial]) namespace?]{ -The same as @base-free-identifier=? in @schememodname[scheme/base].} - -@defproc[(module-transformer-identifier=? [a-id syntax?][b-id syntax?]) boolean?]{ - -The same as @base-free-transformer-identifier=? in @schememodname[scheme/base].} - -@defproc[(module-template-identifier=? [a-id syntax?][b-id syntax?]) boolean?]{ - -The same as @base-free-template-identifier=? in @schememodname[scheme/base].} - -@defproc[(module-label-identifier=? [a-id syntax?][b-id syntax?]) boolean?]{ - -The same as @base-free-label-identifier=? in @schememodname[scheme/base].} +Creates a namespace with @schememodname[mzscheme] attached. If the +@scheme[mode] is empty, the namespace's top-level environment is left +empty. If @scheme[mode] is @scheme['initial], then the namespace's +top-level environment is initialized with +@scheme[(namespace-require/copy 'mzscheme)]. See also +@scheme[make-base-empty-namespace].} +@defproc[(namespace-transformer-require [req any/c]) void?]{ + +Equivalent to @scheme[(namespace-require `(for-syntax ,req))].} + +@deftogether[( +@defproc[(transcript-on [filename any/c]) any] +@defproc[(transcript-off) any] +)]{ + +Raises @scheme[exn:fail], because the operations are not supported.} diff --git a/collects/scheme/mzscheme.ss b/collects/scheme/mzscheme.ss index 3084823fec..dda03fc6e4 100644 --- a/collects/scheme/mzscheme.ss +++ b/collects/scheme/mzscheme.ss @@ -22,13 +22,13 @@ (#%provide require require-for-syntax require-for-template require-for-label provide provide-for-syntax provide-for-label - (all-from-except "private/more-scheme.ss" case) + (all-from-except "private/more-scheme.ss" case old-case) (rename old-case case) (all-from "private/misc.ss") (all-from-except "private/stxcase-scheme.ss" _) (all-from-except "private/letstx-scheme.ss" -define -define-syntax -define-struct - cond else =>) + cond old-cond else =>) (rename old-cond cond) define-struct let-struct identifier? ;; from "private/stx.ss" diff --git a/collects/scribble/manual.ss b/collects/scribble/manual.ss index 77b6fbc910..daf0434bc8 100644 --- a/collects/scribble/manual.ss +++ b/collects/scribble/manual.ss @@ -108,10 +108,15 @@ #f (list . content))) - (define-syntax-rule (defmodule* (name ...) . content) - (begin - (declare-exporting name ...) - (defmodule*/no-declare (name ...) . content))) + (define-syntax defmodule* + (syntax-rules () + [(_ (name ...) #:use-sources (pname ...) . content) + (begin + (declare-exporting name ... #:use-sources (pname ...)) + (defmodule*/no-declare (name ...) . content))] + [(_ (name ...) . content) + (defmodule* (name ...) #:use-sources () . content)])) + (define-syntax-rule (defmodule name . content) (defmodule* (name) . content)) @@ -121,10 +126,14 @@ #t (list . content))) - (define-syntax-rule (defmodulelang* (name ...) . content) - (begin - (declare-exporting name ...) - (defmodulelang*/no-declare (name ...) . content))) + (define-syntax defmodulelang* + (syntax-rules () + [(_ (name ...) #:use-sources (pname ...) . content) + (begin + (declare-exporting name ... #:use-sources (pname ...)) + (defmodulelang*/no-declare (name ...) . content))] + [(_ (name ...) . content) + (defmodulelang* (name ...) #:use-sources () . content)])) (define-syntax-rule (defmodulelang lang . content) (defmodulelang* (lang) . content)) @@ -338,14 +347,38 @@ (annote-exporting-library (to-element (make-just-context name stx-id)))))) - (define (libs->taglet libs) - (and (pair? libs) - (let ([p (resolved-module-path-name - (module-path-index-resolve - (module-path-index-join (car libs) #f)))]) - (if (path? p) - (intern-taglet (path->main-collects-relative p)) - p)))) + (define checkers (make-hash-table 'equal)) + + (define (libs->taglet id libs source-libs) + (let ([lib + (or (ormap (lambda (lib) + (let ([checker (hash-table-get checkers lib + (lambda () + (let ([ns (make-base-empty-namespace)]) + (parameterize ([current-namespace ns]) + (namespace-require `(for-label ,lib))) + (let ([checker + (lambda (id) + (parameterize ([current-namespace ns]) + (let ([new-id (namespace-syntax-introduce + (datum->syntax + #f + (syntax-e id)))]) + (free-label-identifier=? new-id id))))]) + (hash-table-put! checkers lib checker) + checker))))]) + (and (checker id) + lib))) + source-libs) + (and (pair? libs) + (car libs)))]) + (and lib + (let ([p (resolved-module-path-name + (module-path-index-resolve + (module-path-index-join lib #f)))]) + (if (path? p) + (intern-taglet (path->main-collects-relative p)) + p))))) (define (id-to-target-maker id dep?) (*id-to-target-maker 'def id dep?)) @@ -373,7 +406,11 @@ "no declared exporting libraries for definition" id))) (if e - (let* ([lib-taglet (libs->taglet (exporting-libraries-libs e))] + (let* ([lib-taglet (libs->taglet (if sig + (sig-id sig) + id) + (exporting-libraries-libs e) + (exporting-libraries-source-libs e))] [tag (list (if sig (case sym [(def) 'sig-val] @@ -529,11 +566,12 @@ (define-syntax declare-exporting (syntax-rules () - [(_ lib ...) (*declare-exporting '(lib ...))])) + [(_ lib ... #:use-sources (plib ...)) (*declare-exporting '(lib ...) '(plib ...))] + [(_ lib ...) (*declare-exporting '(lib ...) '())])) - (define-struct (exporting-libraries element) (libs)) + (define-struct (exporting-libraries element) (libs source-libs)) - (define (*declare-exporting libs) + (define (*declare-exporting libs source-libs) (make-splice (list (make-part-collect-decl @@ -542,7 +580,7 @@ (lambda (ri) (collect-put! ri '(exporting-libraries #f) libs)))) (make-part-collect-decl - (make-exporting-libraries #f null libs))))) + (make-exporting-libraries #f null libs source-libs))))) (define-syntax (quote-syntax/loc stx) (syntax-case stx () diff --git a/collects/scribblings/gui/gui.scrbl b/collects/scribblings/gui/gui.scrbl index 6456663fe5..87e48fc629 100644 --- a/collects/scribblings/gui/gui.scrbl +++ b/collects/scribblings/gui/gui.scrbl @@ -3,7 +3,7 @@ @title{@bold{GUI}: PLT Graphics Toolkit} -@declare-exporting[scheme/gui/base scheme/gui] +@declare-exporting[scheme/gui/base scheme/gui #:use-sources (mred/mred)] This reference manual describes the GUI toolbox that is part of PLT Scheme and whose core is implemented by the MrEd executable. diff --git a/collects/scribblings/reference/reference.scrbl b/collects/scribblings/reference/reference.scrbl index 2ce72aeae9..1088708cd1 100644 --- a/collects/scribblings/reference/reference.scrbl +++ b/collects/scribblings/reference/reference.scrbl @@ -8,10 +8,20 @@ most prominent libraries. The companion manual @|Guide| provides a friendlier (though less precise and less complete) overview of the language. -@defmodulelang*[(scheme/base scheme)]{Unless otherwise noted, the -bindings defined in this manual are exported by the -@schememodname[scheme/base] and @schememodname[scheme] languages, -where @schememodname[scheme] includes all of +@defmodulelang*[(scheme/base scheme) + ;; Use sources for overlap with `mzscheme': + #:use-sources ('#%kernel + scheme/private/more-scheme + scheme/private/misc + scheme/private/qqstx + scheme/private/stxcase-scheme + scheme/private/letstx-scheme + scheme/private/define + scheme/private/stx)] + +Unless otherwise noted, the bindings defined in this manual are +exported by the @schememodname[scheme/base] and @schememodname[scheme] +languages, where @schememodname[scheme] includes all of @schememodname[scheme/base].} @table-of-contents[] diff --git a/collects/scribblings/scribble/manual.scrbl b/collects/scribblings/scribble/manual.scrbl index b84632be59..b6306d1440 100644 --- a/collects/scribblings/scribble/manual.scrbl +++ b/collects/scribblings/scribble/manual.scrbl @@ -184,7 +184,8 @@ in a form definition.} @; ------------------------------------------------------------------------ @section[#:tag "doc-modules"]{Documenting Modules} -@defform[(defmodule id pre-flow ...)]{ +@defform/subs[(defmodule id maybe-sources pre-flow ...) + ([maybe-sources #:use-sources (mod-path ...)])] Produces a sequence of flow elements (encaptured in a @scheme[splice]) to start the documentation for a module that can be @scheme[require]d @@ -192,27 +193,29 @@ using the path @scheme[id]. The @tech{decode}d @scheme[pre-flow]s introduce the module, but need not include all of the module content. Besides generating text, this form expands to a use of -@scheme[declare-exporting] with @scheme[id]. Consequently, -@scheme[defmodule] should be used at most once in a section, though it -can be shadowed with @scheme[defmodule]s in sub-sections. +@scheme[declare-exporting] with @scheme[id]; the +@scheme[#:use-sources] clause, if provided, is propagated to +@scheme[declare-exporting]. Consequently, @scheme[defmodule] should be +used at most once in a section, though it can be shadowed with +@scheme[defmodule]s in sub-sections. Hyperlinks created by @scheme[schememodname] are associated with the enclosing section, rather than the local @scheme[id] text.} -@defform[(defmodulelang id pre-flow ...)]{ +@defform[(defmodulelang id maybe-sources pre-flow ...)]{ Like @scheme[defmodule], but documents @scheme[id] as a module path suitable for use by either @scheme[require] or @schememodfont{#lang}.} -@defform[(defmodule* (id ...) pre-flow ...)]{ +@defform[(defmodule* (id ...) maybe-sources pre-flow ...)]{ Like @scheme[defmodule], but introduces multiple module paths instead of just one.} -@defform[(defmodulelang* (id ...) pre-flow ...)]{ +@defform[(defmodulelang* (id ...) maybe-sources pre-flow ...)]{ Like @scheme[defmodulelang], but introduces multiple module paths instead of just one.} @@ -233,13 +236,36 @@ Like @scheme[defmodulelang*], but without expanding to @scheme[declare-exporting].} -@defform[(declare-exporting module-path ...)]{ - -Associates the @scheme[module-paths]s to all bindings defined within -the enclosing section, except as overridden by other +@defform/subs[(declare-exporting mod-path ... maybe-sources) + ([maybe-sources #:use-sources (mod-path ...)])]{ + +Associates the @scheme[mod-path]s to all bindings defined within the +enclosing section, except as overridden by other @scheme[declare-exporting] declarations in nested sub-sections. The -list of @scheme[module-path]s is shown, for example, when the user -hovers the mouse over one of the bindings defined within the section. +list of @scheme[mod-path]s is shown, for example, when the user hovers +the mouse over one of the bindings defined within the section. + +More significantly, the first @scheme[mod-path] plus the +@scheme[#:use-sources] @scheme[mod-path]s determine the binding that +is documented by each @scheme[defform], @scheme[defproc], or similar +form within the section that contains the @scheme[declare-exporting] +declaration: + +@itemize{ + + @item{If no @scheme[#:use-sources] clause is supplied, then the + documentation applies to the given name as exported by the first + @scheme[mod-path].} + + @item{If @scheme[#:use-sources] @scheme[mod-path]s are supplied, then + they are tried in order. The first one to provide an export + with the same symbolic name and + @scheme[free-label-identifier=?] to the given name is used as + the documented binding. This binding is assumed to be the same + as the identifier as exported by the first @scheme[mod-path] in + the @scheme[declare-exporting] declaration.} + +} The @scheme[declare-exporting] form should be used no more than once per section, since the declaration applies to the entire section,