change scribble to use new-lambda and new-struct, and correlate definitions and uses via lexical binding

svn: r6714
This commit is contained in:
Matthew Flatt 2007-06-22 05:59:42 +00:00
parent 38f7ef41ed
commit 7de23b6373
48 changed files with 1511 additions and 307 deletions

View File

@ -1,9 +1,8 @@
(module basic mzscheme (module basic (lib "new-lambda.ss" "scribblings")
(require "decode.ss" (require "decode.ss"
"struct.ss" "struct.ss"
"config.ss" "config.ss"
(lib "kw.ss")
(lib "list.ss") (lib "list.ss")
(lib "class.ss")) (lib "class.ss"))
@ -19,23 +18,23 @@
(content->string content) (content->string content)
"_")) "_"))
(define/kw (title #:key [tag #f] [style #f] #:body str) (define (title #:tag [tag #f] #:style [style #f] . str)
(let ([content (decode-content str)]) (let ([content (decode-content str)])
(make-title-decl (or tag (gen-tag content)) style content))) (make-title-decl (or tag (gen-tag content)) style content)))
(define/kw (section #:key [tag #f] #:body str) (define (section #:tag [tag #f] . str)
(let ([content (decode-content str)]) (let ([content (decode-content str)])
(make-part-start 0 (or tag (gen-tag content)) content))) (make-part-start 0 (or tag (gen-tag content)) content)))
(define/kw (subsection #:key [tag #f] #:body str) (define (subsection #:tag [tag #f] . str)
(let ([content (decode-content str)]) (let ([content (decode-content str)])
(make-part-start 1 (or tag (gen-tag content)) content))) (make-part-start 1 (or tag (gen-tag content)) content)))
(define/kw (subsubsection #:key [tag #f] #:body str) (define (subsubsection #:tag [tag #f] . str)
(let ([content (decode-content str)]) (let ([content (decode-content str)])
(make-part-start 2 (or tag (gen-tag content)) content))) (make-part-start 2 (or tag (gen-tag content)) content)))
(define/kw (subsubsub*section #:key [tag #f] #:body str) (define (subsubsub*section #:tag [tag #f] . str)
(let ([content (decode-content str)]) (let ([content (decode-content str)])
(make-paragraph (list (make-element 'bold content))))) (make-paragraph (list (make-element 'bold content)))))
@ -50,7 +49,7 @@
(provide itemize item item?) (provide itemize item item?)
(define/kw (itemize #:body items) (define (itemize . items)
(let ([items (filter (lambda (v) (not (whitespace? v))) items)]) (let ([items (filter (lambda (v) (not (whitespace? v))) items)])
(for-each (lambda (v) (for-each (lambda (v)
(unless (an-item? v) (unless (an-item? v)
@ -63,7 +62,7 @@
(define-struct an-item (flow)) (define-struct an-item (flow))
(define (item? x) (an-item? x)) (define (item? x) (an-item? x))
(define/kw (item #:body str) (define (item . str)
(make-an-item (decode-flow str))) (make-an-item (decode-flow str)))
;; ---------------------------------------- ;; ----------------------------------------
@ -77,28 +76,28 @@
(define (hspace n) (define (hspace n)
(make-element 'hspace (list (make-string n #\space)))) (make-element 'hspace (list (make-string n #\space))))
(define/kw (elem #:body str) (define (elem . str)
(make-element #f (decode-content str))) (make-element #f (decode-content str)))
(define/kw (aux-elem #:body s) (define (aux-elem . s)
(make-aux-element #f (decode-content s))) (make-aux-element #f (decode-content s)))
(define/kw (italic #:body str) (define (italic . str)
(make-element 'italic (decode-content str))) (make-element 'italic (decode-content str)))
(define/kw (bold #:body str) (define (bold . str)
(make-element 'bold (decode-content str))) (make-element 'bold (decode-content str)))
(define/kw (tt #:body str) (define (tt . str)
(make-element 'tt (decode-content str))) (make-element 'tt (decode-content str)))
(define/kw (span-class classname #:body str) (define (span-class classname . str)
(make-element classname (decode-content str))) (make-element classname (decode-content str)))
(define/kw (subscript #:body str) (define (subscript . str)
(make-element 'subscript (decode-content str))) (make-element 'subscript (decode-content str)))
(define/kw (superscript #:body str) (define (superscript . str)
(make-element 'superscript (decode-content str))) (make-element 'superscript (decode-content str)))
;; ---------------------------------------- ;; ----------------------------------------
@ -116,20 +115,20 @@
word-seq word-seq
element-seq)) element-seq))
(define/kw (index* word-seq content-seq #:body s) (define (index* word-seq content-seq . s)
(let ([key (gen-target)]) (let ([key (gen-target)])
(record-index word-seq (record-index word-seq
content-seq content-seq
key key
(decode-content s)))) (decode-content s))))
(define/kw (index word-seq #:body s) (define (index word-seq . s)
(let ([word-seq (if (string? word-seq) (let ([word-seq (if (string? word-seq)
(list word-seq) (list word-seq)
word-seq)]) word-seq)])
(apply index* word-seq word-seq s))) (apply index* word-seq word-seq s)))
(define/kw (as-index #:body s) (define (as-index . s)
(let ([key (gen-target)] (let ([key (gen-target)]
[content (decode-content s)]) [content (decode-content s)])
(record-index (list (content->string content)) (record-index (list (content->string content))

View File

@ -1,11 +1,11 @@
(module doclang mzscheme (module doclang (lib "new-lambda.ss" "scribblings") ; <--- temporary
(require "struct.ss" (require "struct.ss"
"decode.ss" "decode.ss"
(lib "kw.ss")) (lib "kw.ss"))
(require-for-syntax (lib "kerncase.ss" "syntax")) (require-for-syntax (lib "kerncase.ss" "syntax"))
(provide (all-from-except mzscheme #%module-begin) (provide (all-from-except (lib "new-lambda.ss" "scribblings") #%module-begin)
(rename *module-begin #%module-begin)) (rename *module-begin #%module-begin))
;; Module wrapper ---------------------------------------- ;; Module wrapper ----------------------------------------

View File

@ -26,7 +26,7 @@
scribble-eval-handler) scribble-eval-handler)
(define current-int-namespace (make-parameter (make-namespace))) (define current-int-namespace (make-parameter (current-namespace)))
(define scribble-eval-handler (make-parameter (lambda (c? x) (eval x)))) (define scribble-eval-handler (make-parameter (lambda (c? x) (eval x))))
(define image-counter 0) (define image-counter 0)
@ -108,17 +108,11 @@
#f))))))) #f)))))))
(define (do-eval s) (define (do-eval s)
(cond (syntax-case s (code:comment eval:alts)
[(and (list? s) [(code:line v (code:comment . rest))
(eq? 'code:line (car s)) (do-eval #'v)]
(= (length s) 3) [(eval:alts p e)
(list? (caddr s)) (do-eval #'e)]
(eq? 'code:comment (caaddr s)))
(do-eval (cadr s))]
[(and (list? s)
(eq? 'eval:alts (car s))
(= (length s) 3))
(do-eval (caddr s))]
[else [else
(let ([o (open-output-string)]) (let ([o (open-output-string)])
(parameterize ([current-output-port o]) (parameterize ([current-output-port o])
@ -160,17 +154,19 @@
v2)] v2)]
[else v])) [else v]))
(define (strip-comments s) (define (strip-comments stx)
(cond (syntax-case stx (code:comment code:blank)
[(and (pair? s) [((code:comment . _) . rest)
(pair? (car s)) (strip-comments #'rest)]
(eq? (caar s) 'code:comment)) [(a . b)
(strip-comments (cdr s))] (datum->syntax-object stx
[(pair? s) (cons (strip-comments #'a)
(cons (strip-comments (car s)) (strip-comments #'b))
(strip-comments (cdr s)))] stx
[(eq? s 'code:blank) (void)] stx
[else s])) stx)]
[code:blank #'(void)]
[else stx]))
(define (do-plain-eval s catching-exns?) (define (do-plain-eval s catching-exns?)
@ -181,7 +177,7 @@
(syntax-rules () (syntax-rules ()
[(_ e) (#%expression [(_ e) (#%expression
(begin (parameterize ([current-command-line-arguments #()]) (begin (parameterize ([current-command-line-arguments #()])
(do-plain-eval (quote e) #f)) (do-plain-eval (quote-syntax e) #f))
""))])) ""))]))
@ -193,7 +189,7 @@
(syntax-rules () (syntax-rules ()
[(_ e) (#%expression [(_ e) (#%expression
(parameterize ([current-command-line-arguments #()]) (parameterize ([current-command-line-arguments #()])
(show-val (car (do-plain-eval (quote e) #f)))))])) (show-val (car (do-plain-eval (quote-syntax e) #f)))))]))
(define (eval-example-string s) (define (eval-example-string s)
(eval (read (open-input-string s)))) (eval (read (open-input-string s))))
@ -239,7 +235,7 @@
[(_ t schemeinput* e ...) [(_ t schemeinput* e ...)
(interleave t (interleave t
(list (schemeinput* e) ...) (list (schemeinput* e) ...)
(map do-eval (list (quote e) ...)))])) (map do-eval (list (quote-syntax e) ...)))]))
(define-syntax interaction (define-syntax interaction
(syntax-rules () (syntax-rules ()

View File

@ -200,6 +200,11 @@
[(at-right) '((align "right"))] [(at-right) '((align "right"))]
[(at-left) '((align "left"))] [(at-left) '((align "left"))]
[else null]) [else null])
,@(let ([a (and (list? (table-style t))
(assoc 'style (table-style t)))])
(if (and a (string? (cadr a)))
`((class ,(cadr a)))
null))
,@(if (string? (table-style t)) ,@(if (string? (table-style t))
`((class ,(table-style t))) `((class ,(table-style t)))
null)) null))

View File

@ -1,12 +1,11 @@
(module manual mzscheme (module manual (lib "new-lambda.ss" "scribblings")
(require "decode.ss" (require "decode.ss"
"struct.ss" "struct.ss"
"scheme.ss" "scheme.ss"
"config.ss" "config.ss"
"basic.ss" "basic.ss"
(lib "string.ss") (lib "string.ss")
(lib "kw.ss")
(lib "list.ss") (lib "list.ss")
(lib "class.ss")) (lib "class.ss"))
@ -46,7 +45,10 @@
(define (to-element/id s) (define (to-element/id s)
(make-element "schemesymbol" (list (to-element/no-color s)))) (make-element "schemesymbol" (list (to-element/no-color s))))
(define (keep-s-expr ctx s v) s) (define (keep-s-expr ctx s v)
(if (symbol? s)
(make-just-context s ctx)
s))
(define (add-sq-prop s name val) (define (add-sq-prop s name val)
(if (eq? name 'paren-shape) (if (eq? name 'paren-shape)
(make-shaped-parens s val) (make-shaped-parens s val)
@ -97,41 +99,41 @@
link procedure link procedure
idefterm) idefterm)
(define/kw (onscreen #:body str) (define (onscreen . str)
(make-element 'sf (decode-content str))) (make-element 'sf (decode-content str)))
(define (menuitem menu item) (define (menuitem menu item)
(make-element 'sf (list menu "|" item))) (make-element 'sf (list menu "|" item)))
(define/kw (defterm #:body str) (define (defterm . str)
(make-element 'italic (decode-content str))) (make-element 'italic (decode-content str)))
(define/kw (idefterm #:body str) (define (idefterm . str)
(let ([c (decode-content str)]) (let ([c (decode-content str)])
(make-element 'italic c))) (make-element 'italic c)))
(define/kw (schemefont #:body str) (define (schemefont . str)
(apply tt str)) (apply tt str))
(define/kw (schemevalfont #:body str) (define (schemevalfont . str)
(make-element "schemevalue" (decode-content str))) (make-element "schemevalue" (decode-content str)))
(define/kw (schemeresultfont #:body str) (define (schemeresultfont . str)
(make-element "schemeresult" (decode-content str))) (make-element "schemeresult" (decode-content str)))
(define/kw (schemeidfont #:body str) (define (schemeidfont . str)
(make-element "schemesymbol" (decode-content str))) (make-element "schemesymbol" (decode-content str)))
(define/kw (schemeparenfont #:body str) (define (schemeparenfont . str)
(make-element "schemeparen" (decode-content str))) (make-element "schemeparen" (decode-content str)))
(define/kw (schememetafont #:body str) (define (schememetafont . str)
(make-element "schememeta" (decode-content str))) (make-element "schememeta" (decode-content str)))
(define/kw (schemekeywordfont #:body str) (define (schemekeywordfont . str)
(make-element "schemekeyword" (decode-content str))) (make-element "schemekeyword" (decode-content str)))
(define/kw (file #:body str) (define (file . str)
(make-element 'tt (append (list "\"") (decode-content str) (list "\"")))) (make-element 'tt (append (list "\"") (decode-content str) (list "\""))))
(define/kw (exec #:body str) (define (exec . str)
(make-element 'tt (decode-content str))) (make-element 'tt (decode-content str)))
(define/kw (procedure #:body str) (define (procedure . str)
(make-element "schemeresult" (append (list "#<procedure:") (decode-content str) (list ">")))) (make-element "schemeresult" (append (list "#<procedure:") (decode-content str) (list ">"))))
(define/kw (link url #:body str) (define (link url . str)
(make-element (make-target-url url) (decode-content str))) (make-element (make-target-url url) (decode-content str)))
(provide t) (provide t)
(define/kw (t #:body str) (define (t . str)
(decode-paragraph str)) (decode-paragraph str))
(provide schememodule) (provide schememodule)
@ -151,7 +153,7 @@
;; ---------------------------------------- ;; ----------------------------------------
(provide deftech tech) (provide deftech tech techlink)
(define (*tech make-elem style s) (define (*tech make-elem style s)
(let* ([c (decode-content s)] (let* ([c (decode-content s)]
@ -165,12 +167,15 @@
c c
(format "tech-term:~a" s)))) (format "tech-term:~a" s))))
(define/kw (deftech #:body s) (define (deftech . s)
(*tech make-target-element #f (list (apply defterm s)))) (*tech make-target-element #f (list (apply defterm s))))
(define/kw (tech #:body s) (define (tech . s)
(*tech make-link-element "techlink" s)) (*tech make-link-element "techlink" s))
(define (techlink . s)
(*tech make-link-element #f s))
;; ---------------------------------------- ;; ----------------------------------------
(provide defproc defproc* defstruct defthing defform defform* defform/subs defform*/subs defform/none (provide defproc defproc* defstruct defthing defform defform* defform/subs defform*/subs defform/none
@ -218,21 +223,23 @@
(define-syntax defproc (define-syntax defproc
(syntax-rules () (syntax-rules ()
[(_ (id arg ...) result desc ...) [(_ (id arg ...) result desc ...)
(*defproc '[(id arg ...)] (*defproc (list (quote-syntax id))
'[(id arg ...)]
(list (list (lambda () (arg-contract arg)) ...)) (list (list (lambda () (arg-contract arg)) ...))
(list (lambda () (schemeblock0 result))) (list (lambda () (schemeblock0 result)))
(lambda () (list desc ...)))])) (lambda () (list desc ...)))]))
(define-syntax defproc* (define-syntax defproc*
(syntax-rules () (syntax-rules ()
[(_ [[(id arg ...) result] ...] desc ...) [(_ [[(id arg ...) result] ...] desc ...)
(*defproc '[(id arg ...) ...] (*defproc (list (quote-syntax id) ...)
'[(id arg ...) ...]
(list (list (lambda () (arg-contract arg)) ...) ...) (list (list (lambda () (arg-contract arg)) ...) ...)
(list (lambda () (schemeblock0 result)) ...) (list (lambda () (schemeblock0 result)) ...)
(lambda () (list desc ...)))])) (lambda () (list desc ...)))]))
(define-syntax defstruct (define-syntax defstruct
(syntax-rules () (syntax-rules ()
[(_ name fields desc ...) [(_ name fields desc ...)
(*defstruct 'name 'fields (lambda () (list desc ...)))])) (*defstruct (quote-syntax name) 'name 'fields (lambda () (list desc ...)))]))
(define-syntax (defform*/subs stx) (define-syntax (defform*/subs stx)
(syntax-case stx () (syntax-case stx ()
[(_ #:literals (lit ...) [spec spec1 ...] ([non-term-id non-term-form ...] ...) desc ...) [(_ #:literals (lit ...) [spec spec1 ...] ([non-term-id non-term-form ...] ...) desc ...)
@ -245,8 +252,11 @@
'(unsyntax x) '(unsyntax x)
#'name) #'name)
#'rest) #'rest)
#'spec)])]) #'spec)])]
#'(*defforms #t '(lit ...) [spec-id
(syntax-case #'spec ()
[(name . rest) #'name])])
#'(*defforms (quote-syntax spec-id) '(lit ...)
'(spec spec1 ...) '(spec spec1 ...)
(list (lambda (x) (schemeblock0 new-spec)) (list (lambda (x) (schemeblock0 new-spec))
(lambda (ignored) (schemeblock0 spec1)) ...) (lambda (ignored) (schemeblock0 spec1)) ...)
@ -260,6 +270,7 @@
#'(fm #:literals () [spec spec1 ...] ([non-term-id non-term-form ...] ...) desc ...)])) #'(fm #:literals () [spec spec1 ...] ([non-term-id non-term-form ...] ...) desc ...)]))
(define-syntax (defform* stx) (define-syntax (defform* stx)
(syntax-case stx () (syntax-case stx ()
[(_ #:literals lits [spec ...] desc ...) #'(defform*/subs #:literals lits [spec ...] () desc ...)]
[(_ [spec ...] desc ...) #'(defform*/subs [spec ...] () desc ...)])) [(_ [spec ...] desc ...) #'(defform*/subs [spec ...] () desc ...)]))
(define-syntax (defform stx) (define-syntax (defform stx)
(syntax-case stx () (syntax-case stx ()
@ -312,7 +323,7 @@
(define-syntax defthing (define-syntax defthing
(syntax-rules () (syntax-rules ()
[(_ id result desc ...) [(_ id result desc ...)
(*defthing 'id 'result (lambda () (list desc ...)))])) (*defthing (quote-syntax id) 'id 'result (lambda () (list desc ...)))]))
(define-syntax schemegrammar (define-syntax schemegrammar
(syntax-rules () (syntax-rules ()
[(_ #:literals (lit ...) id clause ...) (*schemegrammar '(lit ...) [(_ #:literals (lit ...) id clause ...) (*schemegrammar '(lit ...)
@ -342,7 +353,7 @@
(list (make-table style content)))) (list (make-table style content))))
(list (make-table style content)))) (list (make-table style content))))
(define (*defproc prototypes arg-contractss result-contracts content-thunk) (define (*defproc stx-ids prototypes arg-contractss result-contracts content-thunk)
(let ([spacer (hspace 1)] (let ([spacer (hspace 1)]
[has-optional? (lambda (arg) [has-optional? (lambda (arg)
(and (pair? arg) (and (pair? arg)
@ -378,7 +389,7 @@
(apply (apply
append append
(map (map
(lambda (prototype arg-contracts result-contract first?) (lambda (stx-id prototype arg-contracts result-contract first?)
(append (append
(list (list
(list (make-flow (list (make-flow
@ -403,7 +414,7 @@
(make-target-element (make-target-element
#f #f
(list (to-element (car prototype))) (list (to-element (car prototype)))
(register-scheme-definition (car prototype))) (register-scheme-definition stx-id))
(to-element (car prototype)))) (to-element (car prototype))))
(map arg->elem required) (map arg->elem required)
(if (null? optional) (if (null? optional)
@ -449,25 +460,29 @@
[else null])) [else null]))
(cdr prototype) (cdr prototype)
arg-contracts)))) arg-contracts))))
stx-ids
prototypes prototypes
arg-contractss arg-contractss
result-contracts result-contracts
(cons #t (map (lambda (x) #f) (cdr prototypes)))))) (cons #t (map (lambda (x) #f) (cdr prototypes))))))
(content-thunk)))))) (content-thunk))))))
(define (make-target-element* content wrappers) (define (make-target-element* stx-id content wrappers)
(if (null? wrappers) (if (null? wrappers)
content content
(make-target-element* (make-target-element*
stx-id
(make-target-element (make-target-element
#f #f
(list content) (list content)
(register-scheme-definition (string->symbol (register-scheme-definition
(apply string-append (datum->syntax-object stx-id
(map symbol->string (car wrappers)))))) (string->symbol
(apply string-append
(map symbol->string (car wrappers)))))))
(cdr wrappers)))) (cdr wrappers))))
(define (*defstruct name fields content-thunk) (define (*defstruct stx-id name fields content-thunk)
(define spacer (hspace 1)) (define spacer (hspace 1))
(make-splice (make-splice
(cons (cons
@ -481,6 +496,7 @@
(to-element (to-element
`(,(schemeparenfont "struct") `(,(schemeparenfont "struct")
,(make-target-element* ,(make-target-element*
stx-id
(to-element name) (to-element name)
(let ([name (if (pair? name) (let ([name (if (pair? name)
(car name) (car name)
@ -515,7 +531,7 @@
fields))) fields)))
(content-thunk)))) (content-thunk))))
(define (*defthing name result-contract content-thunk) (define (*defthing stx-id name result-contract content-thunk)
(define spacer (hspace 1)) (define spacer (hspace 1))
(make-splice (make-splice
(cons (cons
@ -528,19 +544,19 @@
(list (make-target-element (list (make-target-element
#f #f
(list (to-element name)) (list (to-element name))
(register-scheme-definition name)) (register-scheme-definition stx-id))
spacer ":" spacer spacer ":" spacer
(to-element result-contract)))))))) (to-element result-contract))))))))
(content-thunk)))) (content-thunk))))
(define (meta-symbol? s) (memq s '(... ...+ ?))) (define (meta-symbol? s) (memq s '(... ...+ ?)))
(define (*defforms kw? lits forms form-procs subs sub-procs content-thunk) (define (*defforms kw-id lits forms form-procs subs sub-procs content-thunk)
(parameterize ([current-variable-list (parameterize ([current-variable-list
(apply (apply
append append
(map (lambda (form) (map (lambda (form)
(let loop ([form (cons (if kw? (cdr form) form) (let loop ([form (cons (if kw-id (cdr form) form)
subs)]) subs)])
(cond (cond
[(symbol? form) (if (or (meta-symbol? form) [(symbol? form) (if (or (meta-symbol? form)
@ -568,22 +584,25 @@
(to-element (to-element
`(,x `(,x
. ,(cdr form))))))) . ,(cdr form)))))))
(and kw? (and kw-id
(eq? form (car forms)) (eq? form (car forms))
(make-target-element (make-target-element
#f #f
(list (to-element (car form))) (list (to-element (make-just-context (car form) kw-id)))
(register-scheme-form-definition (car form))))))))) (register-scheme-form-definition kw-id))))))))
forms form-procs) forms form-procs)
(apply (if (null? sub-procs)
append null
(map (lambda (sub) (list (list (make-flow (list (make-paragraph (list (tt 'nbsp))))))
(list (list (make-flow (list (make-paragraph (list (tt 'nbsp)))))) (list (make-flow (list (let ([l (map (lambda (sub)
(list (make-flow (list (apply *schemerawgrammar (map (lambda (f) (f)) sub))
(map (lambda (f) (f)) sub))))))) sub-procs)])
sub-procs)))) (*schemerawgrammars
"specgrammar"
(map car l)
(map cdr l))))))))))
(content-thunk))))) (content-thunk)))))
(define (*specsubform form has-kw? lits form-thunk subs sub-procs content-thunk) (define (*specsubform form has-kw? lits form-thunk subs sub-procs content-thunk)
(parameterize ([current-variable-list (parameterize ([current-variable-list
(append (let loop ([form (cons (if has-kw? (cdr form) form) (append (let loop ([form (cons (if has-kw? (cdr form) form)
@ -610,41 +629,47 @@
(if form-thunk (if form-thunk
(form-thunk) (form-thunk)
(make-paragraph (list (to-element form))))))) (make-paragraph (list (to-element form)))))))
(apply (if (null? sub-procs)
append null
(map (lambda (sub) (list (list (make-flow (list (make-paragraph (list (tt 'nbsp))))))
(list (list (make-flow (list (make-paragraph (list (tt 'nbsp)))))) (list (make-flow (list (let ([l (map (lambda (sub)
(list (make-flow (list (apply *schemerawgrammar (map (lambda (f) (f)) sub))
(map (lambda (f) (f)) sub))))))) sub-procs)])
sub-procs)))) (*schemerawgrammars
"specgrammar"
(map car l)
(map cdr l))))))))))
(flow-paragraphs (decode-flow (content-thunk))))))) (flow-paragraphs (decode-flow (content-thunk)))))))
(define (*schemerawgrammars nonterms clauseses) (define (*schemerawgrammars style nonterms clauseses)
(make-table (make-table
'((valignment baseline baseline baseline baseline baseline) `((valignment baseline baseline baseline baseline baseline)
(alignment right left center left left)) (alignment right left center left left)
(style ,style))
(let ([empty-line (make-flow (list (make-paragraph (list (tt 'nbsp)))))] (let ([empty-line (make-flow (list (make-paragraph (list (tt 'nbsp)))))]
[to-flow (lambda (i) (make-flow (list (make-paragraph (list i)))))]) [to-flow (lambda (i) (make-flow (list (make-paragraph (list i)))))])
(apply append (cdr
(map (apply append
(lambda (nonterm clauses) (map
(cons (lambda (nonterm clauses)
(list (to-flow nonterm) (list*
empty-line (list empty-line empty-line empty-line empty-line empty-line)
(to-flow "=") (list (to-flow nonterm)
empty-line empty-line
(make-flow (list (car clauses)))) (to-flow "=")
(map (lambda (clause) empty-line
(list empty-line (make-flow (list (car clauses))))
empty-line (map (lambda (clause)
(to-flow "|") (list empty-line
empty-line empty-line
(make-flow (list clause)))) (to-flow "|")
(cdr clauses)))) empty-line
nonterms clauseses))))) (make-flow (list clause))))
(cdr clauses))))
nonterms clauseses))))))
(define (*schemerawgrammar nonterm clause1 . clauses) (define (*schemerawgrammar style nonterm clause1 . clauses)
(*schemerawgrammars (list nonterm) (list (cons clause1 clauses)))) (*schemerawgrammars style (list nonterm) (list (cons clause1 clauses))))
(define (*schemegrammar lits s-expr clauseses-thunk) (define (*schemegrammar lits s-expr clauseses-thunk)
(parameterize ([current-variable-list (parameterize ([current-variable-list
@ -657,7 +682,7 @@
(loop (cdr form)))] (loop (cdr form)))]
[else null]))]) [else null]))])
(let ([l (clauseses-thunk)]) (let ([l (clauseses-thunk)])
(*schemerawgrammars (map car l) (map cdr l))))) (*schemerawgrammars #f (map car l) (map cdr l)))))
(define (*var id) (define (*var id)
(to-element (*var-sym id))) (to-element (*var-sym id)))
@ -668,26 +693,26 @@
;; ---------------------------------------- ;; ----------------------------------------
(provide centerline) (provide centerline)
(define/kw (centerline #:body s) (define (centerline . s)
(make-table 'centered (list (list (make-flow (list (decode-paragraph s))))))) (make-table 'centered (list (list (make-flow (list (decode-paragraph s)))))))
(provide commandline) (provide commandline)
(define/kw (commandline #:body s) (define (commandline . s)
(make-paragraph (list (hspace 2) (apply tt s)))) (make-paragraph (list (hspace 2) (apply tt s))))
(define (secref s) (define (secref s)
(make-link-element #f null `(part ,s))) (make-link-element #f null `(part ,s)))
(define/kw (seclink tag #:body s) (define (seclink tag . s)
(make-link-element #f (decode-content s) `(part ,tag))) (make-link-element #f (decode-content s) `(part ,tag)))
(define/kw (*schemelink id #:body s) (define (*schemelink stx-id id . s)
(make-link-element #f (decode-content s) (register-scheme-definition id))) (make-link-element #f (decode-content s) (register-scheme-definition stx-id)))
(define-syntax schemelink (define-syntax schemelink
(syntax-rules () (syntax-rules ()
[(_ id . content) (*schemelink 'id . content)])) [(_ id . content) (*schemelink (quote-syntax id) 'id . content)]))
(provide secref seclink schemelink) (provide secref seclink schemelink)
(define/kw (pidefterm #:body s) (define (pidefterm . s)
(let ([c (apply defterm s)]) (let ([c (apply defterm s)])
(index (string-append (content->string (element-content c)) "s") (index (string-append (content->string (element-content c)) "s")
c))) c)))
@ -707,7 +732,7 @@
;; ---------------------------------------- ;; ----------------------------------------
(provide math) (provide math)
(define/kw (math #:body s) (define (math . s)
(let ([c (decode-content s)]) (let ([c (decode-content s)])
(make-element #f (apply append (make-element #f (apply append
(map (lambda (i) (map (lambda (i)
@ -727,7 +752,7 @@
(provide cite) (provide cite)
(define/kw (cite #:key key title author location date) (define (cite #:key key #:title title #:author author #:location location #:date date)
"[...]" "[...]"
#; #;
(make-bibliography-element (make-bibliography-element

View File

@ -2,7 +2,8 @@
(require "struct.ss" (require "struct.ss"
"basic.ss" "basic.ss"
(lib "class.ss") (lib "class.ss")
(lib "for.ss")) (lib "for.ss")
(lib "modcollapse.ss" "syntax"))
(provide define-code (provide define-code
to-element to-element
@ -17,7 +18,8 @@
current-variable-list current-variable-list
current-meta-list current-meta-list
(struct shaped-parens (val shape))) (struct shaped-parens (val shape))
(struct just-context (val ctx)))
(define no-color "schemeplain") (define no-color "schemeplain")
(define reader-color "schemeplain") (define reader-color "schemeplain")
@ -32,13 +34,12 @@
(define current-keyword-list (define current-keyword-list
;; This is temporary, until the MzScheme manual is filled in... ;; This is temporary, until the MzScheme manual is filled in...
(make-parameter '(require (make-parameter null #;'(require
provide provide
new send else => and or new send else => and or
define-syntax syntax-rules define-struct define-syntax syntax-rules define-struct
quote quasiquote unquote unquote-splicing quasiquote unquote unquote-splicing
syntax quasisyntax unsyntax unsyntax-splicing syntax quasisyntax unsyntax unsyntax-splicing)))
set! set!-values)))
(define current-variable-list (define current-variable-list
(make-parameter null)) (make-parameter null))
(define current-meta-list (define current-meta-list
@ -353,8 +354,8 @@
(not (or it? is-var?))) (not (or it? is-var?)))
(make-delayed-element (make-delayed-element
(lambda (renderer sec ht) (lambda (renderer sec ht)
(let* ([vtag (register-scheme-definition (syntax-e c))] (let* ([vtag (register-scheme-definition c)]
[stag (register-scheme-form-definition (syntax-e c))] [stag (register-scheme-form-definition c)]
[vd (hash-table-get ht vtag #f)] [vd (hash-table-get ht vtag #f)]
[sd (hash-table-get ht stag #f)]) [sd (hash-table-get ht stag #f)])
(list (list
@ -431,7 +432,7 @@
(cond (cond
[(syntax? v) [(syntax? v)
(let ([mk `(,#'d->s (let ([mk `(,#'d->s
#f (quote-syntax ,v)
,(syntax-case v (uncode) ,(syntax-case v (uncode)
[(uncode e) #'e] [(uncode e) #'e]
[else (stx->loc-s-expr (syntax-e v))]) [else (stx->loc-s-expr (syntax-e v))])
@ -463,11 +464,22 @@
[(_ code typeset-code) #'(define-code code typeset-code unsyntax)])) [(_ code typeset-code) #'(define-code code typeset-code unsyntax)]))
(define (register-scheme-definition sym) (define (register-scheme-definition stx)
(format "definition:~s" sym)) (unless (identifier? stx)
(error 'register-scheme-definition "not an identifier: ~e" (syntax-object->datum stx)))
(format "definition:~s"
(let ([b (identifier-binding stx)])
(cond
[(not b) (format "top:~a" (syntax-e stx))]
[(eq? b 'lexical) (format "lexical:~a" (syntax-e stx))]
[else (format "module:~a:~a"
(if (module-path-index? (car b))
(collapse-module-path-index (car b) '(lib "ack.ss" "scribble"))
(car b))
(cadr b))]))))
(define (register-scheme-form-definition sym) (define (register-scheme-form-definition stx)
(format "formdefinition:~s" sym)) (format "form~s" (register-scheme-definition stx)))
(define syntax-ize-hook (make-parameter (lambda (v col) #f))) (define syntax-ize-hook (make-parameter (lambda (v col) #f)))
@ -495,6 +507,7 @@
l)))) l))))
(define-struct shaped-parens (val shape)) (define-struct shaped-parens (val shape))
(define-struct just-context (val ctx))
(define (syntax-ize v col) (define (syntax-ize v col)
(cond (cond
@ -504,6 +517,13 @@
(syntax-property (syntax-ize (shaped-parens-val v) col) (syntax-property (syntax-ize (shaped-parens-val v) col)
'paren-shape 'paren-shape
(shaped-parens-shape v))] (shaped-parens-shape v))]
[(just-context? v)
(let ([s (syntax-ize (just-context-val v) col)])
(datum->syntax-object (just-context-ctx v)
(syntax-e s)
s
s
(just-context-ctx v)))]
[(and (list? v) [(and (list? v)
(pair? v) (pair? v)
(memq (car v) '(quote unquote unquote-splicing))) (memq (car v) '(quote unquote unquote-splicing)))

View File

@ -184,6 +184,10 @@
background-color: #ddddff; background-color: #ddddff;
} }
.specgrammar {
float: right;
}
.hspace { .hspace {
font-family: Courier; font-size: 80%; font-family: Courier; font-size: 80%;
} }

View File

@ -0,0 +1,400 @@
#reader(lib "docreader.ss" "scribble")
@require[(lib "manual.ss" "scribble")]
@require[(lib "eval.ss" "scribble")]
@require[(lib "class.ss")]
@require["guide-utils.ss"]
@title[#:tag "classes"]{Classes and Objects}
A @scheme[class] expression denotes a first-class value,
just like a @scheme[lambda] expression:
@specform[(class superclass-expr decl-or-expr ...)]
The @scheme[_superclass-expr] determines the superclass for the new
class. Each @scheme[_decl-or-expr] is either a declaration related to
methods, fields, and intialization arguments, or it is an expression
that is evaluated each time that the class is instantiated. In other
words, instead of a method-like constructor, a class has
initialization expressions interleaved with field and method
declarations.
By convention, class names end with @schemeidfont{%}. The built-in root class is
@scheme[object%]. The following expression creates a class with
public methods @scheme[get-size], @scheme[grow], and @scheme[eat]:
@schemeblock[
(class object%
(init size) (code:comment #,(t "initialization argument"))
(define current-size size) (code:comment #,(t "field"))
(super-new) (code:comment #,(t "superclass initialization"))
(define/public (get-size)
current-size)
(define/public (grow amt)
(set! current-size (+ amt current-size)))
(define/public (eat other-fish)
(grow (send other-fish get-size))))
]
@interaction-eval[
(define fish%
(class object%
(init size)
(define current-size size)
(super-new)
(define/public (get-size)
current-size)
(define/public (grow amt)
(set! current-size (+ amt current-size)))
(define/public (eat other-fish)
(grow (send other-fish get-size)))))]
The @scheme[size] initialization argument must be supplied via a named
argument when instantiating the class through the @scheme[new] form:
@schemeblock[
(new (class object% (init size) ...) [size 10])
]
Of course, we can also name the class and its instance:
@schemeblock[
(define fish% (class object% (init size) ...))
(define charlie (new fish% [size 10]))
]
@interaction-eval[(define charlie (new fish% [size 10]))]
In the definition of @scheme[fish%], @scheme[current-size] is a
private field that starts out with the value of the @scheme[size]
initialization argument. Initialization arguments like @scheme[size]
are available only during class instantiation, so they cannot be
referenced directly from a method. The @scheme[current-size] field, in
contrast, is available to methods.
The @scheme[(super-new)] expression in @scheme[fish%] invokes the
initialization of the superclass. In this case, the superclass is
@scheme[object%], which takes no initialization arguments and performs
no work; @scheme[super-new] must be used, anyway, because a class must
always invoke its superclass's initialization.
Initialization arguments, field declarations, and expressions such as
@scheme[(super-new)] can appear in any order within a @scheme[class],
and they can be interleaved with method declarations. The relative
order of expressions in the class determines the order of evaluation
during instantiation. For example, if a field's initial value requires
calling a method that works only after superclass initialization, then
the field declaration is placed after the @scheme[super-new]
call. Ordering field and initialization declarations in this way helps
avoid imperative assignment. The relative order of method declarations
makes no difference for evaluation, because methods are fully defined
before a class is instantiated.
@section[#:tag "guide:methods"]{Methods}
Each of the three @scheme[define/public] declarations in
@scheme[fish%] introduces a new method. The declaration uses the same
syntax as a Scheme function, but a method is not accessible as an
independent function. A call to the @scheme[grow] method of a
@scheme[fish%] object requires the @scheme[send] form:
@interaction[
(send charlie grow 6)
(send charlie get-size)
]
Within @scheme[fish%], self methods can be called like functions,
because the method names are in scope. For example, the @scheme[eat]
method within @scheme[fish%] directly invokes the @scheme[grow]
method. Within a class, attempting to use a method name in any way
other than a method call results in a syntax error.
In some cases, a class must call methods that are supplied by the superclass
but not overridden. In that case, the class can use @scheme[send]
with @scheme[this] to access the method:
@def+int[
(define hungry-fish% (class fish% (super-new)
(define/public (eat-more fish1 fish2)
(send this eat fish1)
(send this eat fish2))))
]
Alternately, the class can declare the existence of a method using @scheme[inherit],
which brings the method name into scope for a direct call:
@def+int[
(define hungry-fish% (class fish% (super-new)
(inherit eat)
(define/public (eat-more fish1 fish2)
(eat fish1) (eat fish2))))
]
With the @scheme[inherit] declaration, if @scheme[fish%] had not
provided an @scheme[eat] method, an error would be signaled in the
evaluation of the @scheme[class] form for @scheme[hungry-fish%]. In
contrast, with @scheme[(send this ...)], an error would not be
signaled until the @scheme[eat-more] method is called and the
@scheme[send] form is evaluated. For this reason, @scheme[inherit] is
preferred.
Another drawback of @scheme[send] is that it is less efficient than
@scheme[inherit]. Invocation of a method via @scheme[send] involves
finding a method in the target object's class at run time, making
@scheme[send] comparable to an interface-based method call in Java. In
contrast, @scheme[inherit]-based method invocations use an offset
within the class's method table that is computed when the class is
created.
To achieve performance similar to @scheme[inherit]-based method calls when
invoking a method from outside the method's class, the programmer must use the
@scheme[generic] form, which produces a class- and method-specific
@defterm{generic method} to be invoked with @scheme[send-generic]:
@def+int[
(define get-fish-size (generic fish% get-size))
(send-generic charlie get-fish-size)
(send-generic (new hungry-fish% [size 32]) get-fish-size)
(send-generic (new object%) get-fish-size)
]
Roughly speaking, the form translates the class and the external
method name to a location in the class's method table. As illustrated
by the last example, sending through a generic method checks that its
argument is an instance of the generic's class.
Whether a method is called directly within a @scheme[class],
through a generic method,
or through @scheme[send], method overriding works in the usual way:
@defs+int[
[
(define picky-fish% (class fish% (super-new)
(define/override (grow amt)
;; Doesn't eat all of its food
(super grow (* 3/4 amt)))))
(define daisy (new picky-fish% [size 20]))
]
(send daisy eat charlie)
(send daisy get-size)
]
The @scheme[grow] method in @scheme[picky-fish%] is declared with
@scheme[define/override] instead of @scheme[define/public], because
@scheme[grow] is meant as an overriding declaration. If @scheme[grow]
had been declared with @scheme[define/public], an error would have
been signaled when evaluating the @scheme[class] expression, because
@scheme[fish%] already supplies @scheme[grow].
Using @scheme[define/override] also allows the invocation of the
overridden method via a @scheme[super] call. For example, the
@scheme[grow] implementation in @scheme[picky-fish%] uses
@scheme[super] to delegate to the superclass implementation.
@section[#:tag "guide:initargs"]{Initialization Arguments}
Since @scheme[picky-fish%] declares no initialization arguments, any
initialization values supplied in @scheme[(new picky-fish% ...)] are
propagated to the superclass initialization, i.e., to @scheme[fish%].
A subclass can supply additional initialization arguments for its
superclass in a @scheme[super-new] call, and such initialization
arguments take precedence over arguments supplied to @scheme[new]. For
example, the following @scheme[size-10-fish%] class always generates
fish of size 10:
@def+int[
(define size-10-fish% (class fish% (super-new [size 10])))
(send (new size-10-fish%) get-size)
]
In the case of @scheme[size-10-fish%], supplying a @scheme[size]
initialization argument with @scheme[new] would result in an
initialization error; because the @scheme[size] in @scheme[super-new]
takes precedence, a @scheme[size] supplied to @scheme[new] would have
no target declaration.
An initialization argument is optional if the @scheme[class] form
declares a default value. For example, the following @scheme[default-10-fish%]
class accepts a @scheme[size] initialization argument, but its value defaults to
10 if no value is supplied on instantiation:
@def+int[
(define default-10-fish% (class fish%
(init [size 10])
(super-new [size size])))
(new default-10-fish%)
(new default-10-fish% [size 20])
]
In this example, the @scheme[super-new] call propagates its own
@scheme[size] value as the @scheme[size] initialization argument to
the superclass.
@section[#:tag "guide:intnames"]{Internal and External Names}
The two uses of @scheme[size] in @scheme[default-10-fish%] expose the
double life of class-member identifiers. When @scheme[size] is the
first identifier of a bracketed pair in @scheme[new] or
@scheme[super-new], @scheme[size] is an @defterm{external name} that
is symbolically matched to an initialization argument in a class. When
@scheme[size] appears as an expression within
@scheme[default-10-fish%], @scheme[size] is an \defterm{internal name}
that is lexically scoped. Similarly, a call to an inherited
@scheme[eat] method uses @scheme[eat] as an internal name, whereas a
@scheme[send] of @scheme[eat] uses @scheme[eat] as an external name.
The full syntax of the @scheme[class] form allows a programmer to
specify distinct internal and external names for a class member. Since
internal names are local, they can be renamed to avoid shadowing or
conflicts. Such renaming is not frequently necessary, but workarounds
in the absence of renaming can be especially cumbersome.
@section{Interfaces}
Interfaces are useful for checking that an object or a class
implements a set of methods with a particular (implied) behavior.
This use of interfaces is helpful even without a static type system
(which is the main reason that Java has interfaces).
An interface in PLT Scheme is created using the @scheme[interface]
form, which merely declares the method names required to implement the
interface. An interface can extend other interfaces, which means that
implementations of the interface automatically implement the extended
interfaces.
@specform[(interface (superinterface-expr ...) id ...)]
To declare that a class implements an interface, the
@scheme[class*] form must be used instead of @scheme[class]:
@specform[(class* superclass-expr (interface-expr ...) decl-or-expr ...)]
For example, instead of forcing all fish classes to be derived from
@scheme[fish%], we can define @scheme[fish-interface] and change the
@scheme[fish%] class to declare that it implements
@scheme[fish-interface]:
@schemeblock[
(define fish-interface (interface () get-size grow eat))
(define fish% (class* object% (fish-interface) ...))
]
If the definition of @scheme[fish%] does not include
@scheme[get-size], @scheme[grow], and @scheme[eat] methods, then an
error is signaled in the evaluation of the @scheme[class*] form,
because implementing the @scheme[fish-interface] interface requires
those methods.
The @scheme[is-a?] predicate accepts either a class or interface as
its first argument and an object as its second argument. When given a
class, @scheme[is-a?] checks whether the object is an instance of that
class or a derived class. When given an interface, @scheme[is-a?]
checks whether the object's class implements the interface. In
addition, the @scheme[implementation?] predicate checks whether a
given class implements a given interface.
@section[#:tag "guide:inner"]{Final, Augment, and Inner}
As in Java, a method in a @scheme[class] form can be specified as
@defterm{final}, which means that a subclass cannot override the
method. A final method is declared using @scheme[public-final] or
@scheme[override-final], depending on whether the declaration is for a
new method or an overriding implementation.
Between the extremes of allowing arbitrary overriding and disallowing
overriding entirely, the {class} system also supports Beta-style
@defterm{augmentable} methods~\cite{beta}. A method
declared with @scheme[pubment] is like @scheme[public], but the method
cannot be overridden in subclasses; it can be augmented only. A
@scheme[pubment] method must explicitly invoke an augmentation (if any)
using @scheme[inner]; a subclass augments the method using
@scheme[augment], instead of @scheme[override].
In general, a method can switch between augment and override modes in
a class derivation. The @scheme[augride] method specification
indicates an augmentation to a method where the augmentation is itself
overrideable in subclasses (though the superclass's implementation
cannot be overridden). Similarly, @scheme[overment] overrides a method
and makes the overriding implementation augmentable. Our earlier
work~\cite{Super+Inner} motivates and explains these extensions and
their interleaving.
@section[#:tag "guide:extnames"]{Controlling the Scope of External Names}
As noted in @secref["guide:intnames"], class members have both
internal and external names. A member definition binds an internal
name locally, and this binding can be locally renamed. External
names, in contrast, have global scope by default, and a member
definition does not bind an external name. Instead, a member
definition refers to an existing binding for an external name, where
the member name is bound to a @defterm{member key}; a class ultimately
maps member keys to methods, fields, and initialization arguments.
Recall the @scheme[hungry-fish%] @scheme[class] expression:
@schemeblock[
(define hungry-fish% (class fish% ...
(inherit eat)
(define/public (eat-more fish1 fish2)
(eat fish1) (eat fish2))))
]
During its evaluation, the @scheme[hungry-fish%] and @scheme[fish%]
classes refer to the same global binding of @scheme[eat]. At run
time, calls to @scheme[eat] in @scheme[hungry-fish%] are matched with
the @scheme[eat] method in @scheme[fish%] through the shared method
key that is bound to @scheme[eat].
The default binding for an external name is global, but a
programmer can introduce an external-name binding with the
@scheme[define-member-name] form.
@specform[(define-member-name id member-key-expr)]
In particular, by using @scheme[(generate-member-key)] as the
@scheme[member-key-expr], an external name can be localized for a
particular scope, because the generated member key is inaccessible
outside the scope. In other words, @scheme[define-member-name] gives
an external name a kind of package-private scope, but generalized from
packages to arbitrary binding scopes in Scheme.
For example, the following @scheme[fish%] and @scheme[pond%] classes cooperate
via a @scheme[get-depth] method that is only accessible to the
cooperating classes:
@schemeblock[
(define-values (fish% pond%) (code:comment #,(t "two mutually recursive classes"))
(let () ; create a local definition scope
(define-member-name get-depth (generate-member-key))
(define fish%
(class ... (define my-depth ...)
(define my-pond ...)
(define/public (dive amt)
(set! my-depth
(min (+ my-depth amt)
(send my-pond get-depth))))))
(define pond%
(class ... (define current-depth ...)
(define/public (get-depth) current-depth)))
(values fish% pond%)))
]
External names are in a namespace that separates them from other Scheme
names. This separate namespace is implicitly used for the method name in
@scheme[send], for initialization-argument names in @scheme[new], or for
the external name in a member definition. The special
@scheme[member-name-key] provides access to the binding of an external name
in an arbitrary expression position: @scheme[(member-name-key id)] form
produces the member-key binding of @scheme[id] in the current scope.
A member-key value is primarily used on with a
@scheme[define-member-name] form. Normally, then,
@scheme[(member-name-key id)] captures the method key of @scheme[id]
so that it can be communicated to a use of @scheme[define-member-name]
in a different scope. This capability turns out to be useful for
generalizing mixins (see \SecRef{sec:parammixins}).

View File

@ -133,8 +133,8 @@ To make a structure type @defterm{transparent}, use the
field-name sequence: field-name sequence:
@def+int[ @def+int[
'(define-struct posn (x y) (define-struct posn (x y)
#:inspector #f) #:inspector #f)
(make-posn 1 2) (make-posn 1 2)
] ]

View File

@ -2,8 +2,7 @@
@require[(lib "manual.ss" "scribble")] @require[(lib "manual.ss" "scribble")]
@require[(lib "eval.ss" "scribble")] @require[(lib "eval.ss" "scribble")]
@require["guide-utils.ss"] @require["guide-utils.ss"]
@require[(lib "string.ss")]
@interaction-eval[(require (lib "string.ss"))]
@title{Definitions: @scheme[define]} @title{Definitions: @scheme[define]}

View File

@ -2,8 +2,7 @@
@require[(lib "manual.ss" "scribble")] @require[(lib "manual.ss" "scribble")]
@require[(lib "eval.ss" "scribble")] @require[(lib "eval.ss" "scribble")]
@require["guide-utils.ss"] @require["guide-utils.ss"]
@require[(lib "for.ss")]
@interaction-eval[(require (lib "for.ss"))]
@title[#:tag "guide:for"]{Iterations and Comprehensions} @title[#:tag "guide:for"]{Iterations and Comprehensions}

View File

@ -1,13 +1,10 @@
(module guide-utils mzscheme (module guide-utils (lib "new-lambda.ss" "scribblings")
(require (lib "manual.ss" "scribble") (require (lib "manual.ss" "scribble")
(lib "struct.ss" "scribble") (lib "struct.ss" "scribble")
(lib "decode.ss" "scribble") (lib "decode.ss" "scribble")
(lib "kw.ss") (lib "kw.ss")
(lib "eval.ss" "scribble")) (lib "eval.ss" "scribble"))
(interaction-eval (require (lib "new-lambda.ss" "scribblings")))
(provide Quick MzScheme HtDP (provide Quick MzScheme HtDP
tool tool
refdetails refdetails
@ -26,7 +23,7 @@
(define (tool name . desc) (define (tool name . desc)
(apply item (bold name) ", " desc)) (apply item (bold name) ", " desc))
(define/kw (refdetails* tag what #:body s) (define (refdetails* tag what . s)
(apply margin-note (apply margin-note
(decode-content (append (list "For " what " on ") (decode-content (append (list "For " what " on ")
s s
@ -34,10 +31,10 @@
(refsecref tag) (refsecref tag)
"."))))) ".")))))
(define/kw (refdetails tag #:body s) (define (refdetails tag . s)
(apply refdetails* tag "more" s)) (apply refdetails* tag "more" s))
(define/kw (refdetails/gory tag #:body s) (define (refdetails/gory tag . s)
(apply refdetails* tag "gory details" s)) (apply refdetails* tag "gory details" s))
(define (refsecref s) (define (refsecref s)

View File

@ -38,7 +38,7 @@ describes the acceptable arguments and the result of the procedure
using @idefterm{contracts}. using @idefterm{contracts}.
@; ---------------------------------------------------------------------- @; ----------------------------------------------------------------------
@section[#:tag "classes"]{Classes and Objects} @include-section["class.scrbl"]
@; ---------------------------------------------------------------------- @; ----------------------------------------------------------------------

View File

@ -3,8 +3,6 @@
@require[(lib "eval.ss" "scribble")] @require[(lib "eval.ss" "scribble")]
@require["guide-utils.ss"] @require["guide-utils.ss"]
@interaction-eval[(require (lib "file.ss"))]
@title{Local Binding} @title{Local Binding}
Although internal @scheme[define]s can be used for local binding, Although internal @scheme[define]s can be used for local binding,

View File

@ -3,9 +3,9 @@
@require[(lib "eval.ss" "scribble")] @require[(lib "eval.ss" "scribble")]
@require[(lib "bnf.ss" "scribble")] @require[(lib "bnf.ss" "scribble")]
@require["guide-utils.ss"] @require["guide-utils.ss"]
@require[(lib "list.ss")]
@require[(lib "for.ss")]
@interaction-eval[(require (lib "list.ss"))]
@interaction-eval[(require (lib "for.ss"))]
@define[step @elem{=}] @define[step @elem{=}]
@title{Lists, Iteration, and Recursion} @title{Lists, Iteration, and Recursion}
@ -212,12 +212,12 @@ argument @scheme[len]:
@schemeblock[ @schemeblock[
(define (my-length lst) (define (my-length lst)
(code:comment #, @elem{local function @scheme[iter]:}) (code:comment #, @t{local function @scheme[iter]:})
(define (iter lst len) (define (iter lst len)
(cond (cond
[(empty? lst) len] [(empty? lst) len]
[else (iter (rest lst) (+ len 1))])) [else (iter (rest lst) (+ len 1))]))
(code:comment #, @elem{body of @scheme[my-length] calls @scheme[iter]:}) (code:comment #, @t{body of @scheme[my-length] calls @scheme[iter]:})
(iter lst 0)) (iter lst 0))
] ]

View File

@ -2,9 +2,8 @@
@require[(lib "manual.ss" "scribble")] @require[(lib "manual.ss" "scribble")]
@require[(lib "eval.ss" "scribble")] @require[(lib "eval.ss" "scribble")]
@require["guide-utils.ss"] @require["guide-utils.ss"]
@require[(lib "list.ss")]
@interaction-eval[(require (lib "list.ss"))] @define[mutable-cons cons]
@interaction-eval[(define mutable-cons cons)]
@title{Pairs and Lists} @title{Pairs and Lists}

View File

@ -2,8 +2,7 @@
@require[(lib "manual.ss" "scribble")] @require[(lib "manual.ss" "scribble")]
@require[(lib "eval.ss" "scribble")] @require[(lib "eval.ss" "scribble")]
@require["guide-utils.ss"] @require["guide-utils.ss"]
@require[(lib "list.ss")]
@interaction-eval[(require (lib "list.ss"))]
@title{Pairs, Lists, and Scheme Syntax} @title{Pairs, Lists, and Scheme Syntax}

View File

@ -1,15 +1,18 @@
(module new-lambda mzscheme (module new-lambda mzscheme
(require-for-syntax (lib "name.ss" "syntax") (require-for-syntax (lib "name.ss" "syntax")
(lib "define.ss" "syntax")) (lib "define.ss" "syntax"))
(require "new-struct.ss")
(provide (all-from-except mzscheme #%datum lambda define #%app) (provide (all-from-except mzscheme #%datum lambda define #%app define-struct)
(rename new-datum #%datum) (rename new-datum #%datum)
(rename new-lambda lambda) (rename new-lambda lambda)
(rename new-define define) (rename new-define define)
(rename new-app #%app) (rename new-app #%app)
(rename *make-keyword-procedure make-keyword-procedure) (rename *make-keyword-procedure make-keyword-procedure)
keyword-apply keyword-apply
procedure-keywords) procedure-keywords
(rename define-struct* define-struct)
struct-field-index)
;; ---------------------------------------- ;; ----------------------------------------
@ -366,7 +369,7 @@
(make-optional-keyword-procedure (make-optional-keyword-procedure
with-kws with-kws
null null
'(kw ...) 'kws
no-kws))))] no-kws))))]
[else [else
;; just the keywords part dispatches to core, ;; just the keywords part dispatches to core,

View File

@ -0,0 +1,413 @@
;; Based on
;; (planet "struct.ss" ("ryanc" "macros.plt" 1 0)))
;; though, strangely and embarassingly, Matthew didn't know that until
;; after he had mostly re-implemented it.
(module new-struct mzscheme
(require (lib "stxparam.ss"))
(provide define-struct*
struct-field-index)
(define-syntax-parameter struct-field-index
(lambda (stx)
(raise-syntax-error #f "allowed only within a structure type definition" stx)))
(define (check-struct-type name what)
(when what
(unless (struct-type? what)
(raise-type-error name "struct-type or #f" what)))
what)
(define (check-inspector name what)
(when what
(unless (inspector? what)
(raise-type-error name "inspector or #f" what)))
what)
(define-syntax (define-struct* stx)
(define make-field list)
(define field-id car)
(define field-default-value cadr)
(define field-auto? caddr)
(define field-immutable? cadddr)
(define (struct-declaration-info? x)
(define (identifier/#f? x)
(or (not x)
(identifier? x)))
(define (id/#f-list? id? x)
(or (null? x)
(and (pair? x)
(if (null? (cdr x))
(identifier/#f? (car x))
(and (id? (car x))
(id/#f-list? id? (cdr x)))))))
(and (list? x)
(= (length x) 6)
(identifier/#f? (car x))
(identifier/#f? (cadr x))
(identifier/#f? (caddr x))
(id/#f-list? identifier? (list-ref x 3))
(id/#f-list? identifier/#f? (list-ref x 4))
(or (eq? #t (list-ref x 5)) (identifier/#f? (list-ref x 5)))))
(define (build-name id . parts)
(datum->syntax-object
id
(string->symbol
(apply string-append
(map (lambda (p)
(if (syntax? p)
(symbol->string (syntax-e p))
p))
parts)))
id))
(define (bad why kw where)
(raise-syntax-error
#f
(format "~a ~a specification~a"
why
(syntax-e kw)
where)
stx
kw))
(define (check-exprs n ps)
(let loop ([nps (cdr ps)][n n])
(unless (zero? n)
(unless (and (pair? nps)
(not (keyword? (syntax-e (car nps)))))
(raise-syntax-error
#f
(format "expected ~a expression~a after keyword~a"
n
(if (= n 1) "" "s")
(if (pair? nps)
", found a keyword"
""))
stx
(car ps)))
(loop (cdr nps) (sub1 n)))))
;; Parse one field with a sequence of keyword-based specs:
(define (parse-field f)
(syntax-case f ()
[id
(identifier? #'id)
(make-field #'id #f #f #f)]
[(id p ...)
(identifier? #'id)
(let loop ([ps (syntax->list #'(p ...))]
[def-val #f]
[auto? #f]
[immutable? #f])
(cond
[(null? ps) (make-field #'id def-val auto? immutable?)]
[(eq? #:immutable (syntax-e (car ps)))
(when immutable?
(bad "redundant" (car ps) " for field"))
(loop (cdr ps) def-val auto? #t)]
[(eq? #:default (syntax-e (car ps)))
(check-exprs 1 ps)
(when def-val
(bad "multiple" (car ps) " for field"))
(loop (cddr ps) (cadr ps) auto? immutable?)]
[(eq? #:auto (syntax-e (car ps)))
(when auto?
(bad "redundant" (car ps) " for field"))
(loop (cdr ps) def-val #t immutable?)]
[else
(raise-syntax-error
#f
(if (keyword? (syntax-e (car ps)))
"unrecognized field-specification keyword"
"expected a field-spefication keyword")
stx
(car ps))]))]
[_else
(raise-syntax-error
#f
"expected a field identifier or a parenthesized identifier and field-specification sequence"
stx
f)]))
(define (lookup config s)
(cdr (assq s config)))
(define (extend-config config s val)
(cond
[(null? config) (error 'struct "internal error: can't find config element: ~s" s)]
[(eq? (caar config) s) (cons (cons s val) (cdr config))]
[else (cons (car config) (extend-config (cdr config) s val))]))
;; Parse sequence of keyword-based struct specs
(define (parse-props p super-id)
(let loop ([p p]
[config '((#:super . #f)
(#:inspector . #f)
(#:auto-value . #f)
(#:props . ())
(#:immutable . #f)
(#:guard . #f)
(#:omit-define-values . #f)
(#:omit-define-syntaxes . #f))])
(cond
[(null? p) config]
[(eq? #:super (syntax-e (car p)))
(check-exprs 1 p)
(when (lookup config '#:super)
(bad "multiple" (car p) ""))
(when super-id
(raise-syntax-error
#f
(string-append
"#:super specification disallowed because a struct supertype id"
" was supplied with the struct type id")
stx
(car p)))
(loop (cddr p)
(extend-config config '#:super (cadr p)))]
[(memq (syntax-e (car p))
'(#:inspector #:guard #:auto-value))
(let ([key (syntax-e (car p))])
(check-exprs 1 p)
(when (lookup config key)
(bad "multiple" (car p) ""))
(loop (cddr p)
(extend-config config key (cadr p))))]
[(eq? #:property (syntax-e (car p)))
(check-exprs 2 p)
(loop (cdddr p)
(extend-config config
'#:props
(cons (cons (cadr p) (caddr p))
(lookup config '#:props))))]
[(memq (syntax-e (car p))
'(#:immutable #:omit-define-values #:omit-define-syntaxes))
(let ([key (syntax-e (car p))])
(when (lookup config key)
(bad "redundant" (car p) ""))
(loop (cdr p)
(extend-config config key #t)))]
[else
(raise-syntax-error
#f
(if (keyword? (syntax-e (car p)))
"unrecognized struct-specification keyword"
"expected a struct-spefication keyword")
stx
(car p))])))
(syntax-case stx ()
[(fm id (field ...) prop ...)
(let-values ([(id super-id)
(if (identifier? #'id)
(values #'id #f)
(syntax-case #'id ()
[(id super-id)
(and (identifier? #'id)
(identifier? #'super-id))
(values #'id #'super-id)]
[else
(raise-syntax-error
#f
(string-append
"expected an identifier for the struct type name, or a parenthesized sequence"
" with an identifier followed by the struct supertype identifier")
stx)]))])
(let ([super-info
(and super-id
(let ([v (syntax-local-value super-id (lambda () #f))])
(if (struct-declaration-info? v)
v
(raise-syntax-error
#f
(format "parent struct type not defined~a"
(if v
(format " (~a does not name struct type information)"
(syntax-e super-id))
""))
stx
super-id))))])
(when (and super-info
(not (car super-info)))
(raise-syntax-error
#f
"no structure type descriptor available for supertype"
stx
super-id))
(let* ([field-stxes (syntax->list #'(field ...))]
[fields (map parse-field field-stxes)]
[dup (check-duplicate-identifier (map field-id fields))])
(when dup
(raise-syntax-error
#f
"duplicate field identifier"
stx
dup))
(let ([auto-count
(let loop ([fields fields] [field-stxes field-stxes] [auto? #f])
(cond
[(null? fields) 0]
[(field-auto? (car fields))
(+ 1 (loop (cdr fields) (cdr field-stxes) #t))]
[auto?
(raise-syntax-error
#f
"non-auto field after an auto field disallowed"
stx
(car field-stxes))]
[else
(loop (cdr fields) (cdr field-stxes) #f)]))])
(let-values ([(inspector super-expr props auto-val guard immutable?
omit-define-values? omit-define-syntaxes?)
(let ([config (parse-props (syntax->list #'(prop ...)) super-id)])
(values (lookup config '#:inspector)
(lookup config '#:super)
(lookup config '#:props)
(lookup config '#:auto-value)
(lookup config '#:guard)
(lookup config '#:immutable)
(lookup config '#:omit-define-values)
(lookup config '#:omit-define-syntaxes)))])
(when immutable?
(for-each (lambda (f f-stx)
(when (field-immutable? f)
(raise-syntax-error
#f
"redundant #:immutable specification in field"
stx
f-stx)))
fields field-stxes))
(let ([struct: (build-name id "struct:" id)]
[make- (build-name id "make-" id)]
[? (build-name id id "?")]
[sels (map (lambda (f)
(build-name (field-id f)
id "-" (field-id f)))
fields)]
[sets (if immutable?
null
(let loop ([fields fields])
(cond
[(null? fields) null]
[(field-immutable? (car fields))
(loop (cdr fields))]
[else
(cons (build-name (field-id (car fields))
"set-"
id
"-"
(field-id (car fields))
"!")
(loop (cdr fields)))])))]
[super-struct: (if super-info
(or (car super-info)
(raise-syntax-error
#f
"no structure type descriptor available for supertype"
stx
super-id))
(and super-expr
#`(check-struct-type 'fm #,super-expr)))])
(let ([run-time-defns
(lambda ()
(quasisyntax/loc stx
(define-values (#,struct: #,make- #,? #,@sels #,@sets)
(let-values ([(struct: make- ? -ref -set!)
(syntax-parameterize ([struct-field-index
(lambda (stx)
(syntax-case stx #,(map field-id fields)
#,@(let loop ([fields fields][pos 0])
(cond
[(null? fields) null]
[else (cons #`[(_ #,(field-id (car fields))) #'#,pos]
(loop (cdr fields) (add1 pos)))]))
[(_ name) (raise-syntax-error #f "no such field" stx #'name)]))])
(make-struct-type '#,id
#,super-struct:
#,(- (length fields) auto-count)
#,auto-count
#,auto-val
#,(if (null? props)
#'null
#`(list #,@(map (lambda (p)
#`(cons #,(car p) #,(cdr p)))
props)))
#,(if inspector
#`(check-inspector 'fm #,inspector)
#`(current-inspector))
#f
'#,(let loop ([i 0]
[fields fields])
(cond
[(null? fields) null]
[(or immutable? (field-immutable? (car fields)))
(cons i (loop (add1 i) (cdr fields)))]
[else (loop (add1 i) (cdr fields))]))
#,guard))])
(values struct: make- ?
#,@(let loop ([i 0][fields fields])
(if (null? fields)
null
(cons #`(make-struct-field-accessor -ref #,i '#,(field-id (car fields)))
(loop (add1 i) (cdr fields)))))
#,@(if immutable?
null
(let loop ([i 0][fields fields])
(if (null? fields)
null
(if (field-immutable? (car fields))
(loop (add1 i) (cdr fields))
(cons #`(make-struct-field-mutator -set! #,i '#,(field-id (car fields)))
(loop (add1 i) (cdr fields))))))))))))]
[compile-time-defns
(lambda ()
(let ([protect (lambda (sel)
(if (syntax-e sel)
#`(c (quote-syntax #,sel))
sel))])
(quasisyntax/loc stx
(define-syntaxes (#,id)
(let ([c (syntax-local-certifier)])
(list-immutable
(c (quote-syntax #,struct:))
(c (quote-syntax #,make-))
(c (quote-syntax #,?))
(list-immutable
#,@(map protect sels)
#,@(if super-info
(map protect (list-ref super-info 3))
(if super-expr
'(#f)
null)))
(list-immutable
#,@(let loop ([fields fields][sets sets])
(cond
[(null? fields) null]
[(or immutable? (field-immutable? (car fields)))
(cons #f (loop (cdr fields) sets))]
[else
(cons (protect (car sets))
(loop (cdr fields) (cdr sets)))]))
#,@(if super-info
(map protect (list-ref super-info 4))
(if super-expr
'(#f)
null)))
#,(if super-id
(protect super-id)
(if super-expr
#f
#t))))))))])
(cond
[(and (not omit-define-values?) (not omit-define-syntaxes?))
#`(begin #,(run-time-defns) #,(compile-time-defns))]
[omit-define-syntaxes?
(run-time-defns)]
[omit-define-values?
(compile-time-defns)]
[else #'(begin)]))))))))])))

View File

@ -1,7 +1,3 @@
(0 () 0 () () (c! require c! (c! lib c! "slideshow.ss" c! "slideshow")))
(0 () 0 () () (void))
(0 () 0 () () (c! require-for-syntax c! mzscheme))
(0 () 0 () () (void))
(0 () 0 () () 5) (0 () 0 () () 5)
(0 () 0 () () 5) (0 () 0 () () 5)
(0 () 0 () () "art gallery") (0 () 0 () () "art gallery")

Binary file not shown.

Before

Width:  |  Height:  |  Size: 209 B

After

Width:  |  Height:  |  Size: 205 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 102 B

After

Width:  |  Height:  |  Size: 102 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 710 B

After

Width:  |  Height:  |  Size: 658 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 143 B

After

Width:  |  Height:  |  Size: 143 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 209 B

After

Width:  |  Height:  |  Size: 205 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 77 B

After

Width:  |  Height:  |  Size: 77 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 300 B

After

Width:  |  Height:  |  Size: 288 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 837 B

After

Width:  |  Height:  |  Size: 819 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 102 B

After

Width:  |  Height:  |  Size: 102 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 300 B

After

Width:  |  Height:  |  Size: 288 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 388 B

After

Width:  |  Height:  |  Size: 372 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 77 B

After

Width:  |  Height:  |  Size: 77 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 242 B

After

Width:  |  Height:  |  Size: 236 B

View File

@ -0,0 +1,18 @@
(module mred-doc mzscheme
(define mr-eval? (getenv "MREVAL"))
(define-syntax bounce
(syntax-rules ()
[(_ id)
(begin
(provide id)
(define id (if mr-eval?
(dynamic-require '(lib "mred.ss" "mred") 'id)
#f)))]
[(_ id ...)
(begin (bounce id) ...)]))
(bounce frame% canvas%
bitmap% bitmap-dc%
color%))

View File

@ -7,6 +7,8 @@
(lib "file.ss") (lib "file.ss")
(lib "runtime-path.ss") (lib "runtime-path.ss")
(lib "serialize.ss") (lib "serialize.ss")
"slideshow-doc.ss"
"mred-doc.ss"
(lib "exn.ss" "scribblings" "quick")) (lib "exn.ss" "scribblings" "quick"))
(define-syntax define-mr (define-syntax define-mr
@ -17,8 +19,7 @@
(define-syntax mr (define-syntax mr
(syntax-rules () (syntax-rules ()
[(_ x (... ...)) [(_ x (... ...))
(parameterize ([scribble-eval-handler mr-eval-handler] (parameterize ([scribble-eval-handler mr-eval-handler])
[current-int-namespace mr-namespace])
(orig x (... ...)))])))])) (orig x (... ...)))])))]))
(define-mr mr-interaction interaction) (define-mr mr-interaction interaction)
@ -46,7 +47,7 @@
(let ([eh (scribble-eval-handler)] (let ([eh (scribble-eval-handler)]
[log-file (open-output-file exprs-dat-file 'truncate/replace)]) [log-file (open-output-file exprs-dat-file 'truncate/replace)])
(lambda (catching-exns? expr) (lambda (catching-exns? expr)
(write (serialize expr) log-file) (write (serialize (syntax-object->datum expr)) log-file)
(newline log-file) (newline log-file)
(flush-output log-file) (flush-output log-file)
(let ([result (let ([result
@ -76,7 +77,7 @@
(if (eof-object? v) (if (eof-object? v)
(error "expression not in log file") (error "expression not in log file")
(let ([v (deserialize v)]) (let ([v (deserialize v)])
(if (equal? v expr) (if (equal? v (syntax-object->datum expr))
(let ([v (read log-file)]) (let ([v (read log-file)])
(if (eof-object? v) (if (eof-object? v)
(error "expression result missing in log file") (error "expression result missing in log file")
@ -91,50 +92,22 @@
expr expr
v)))))))))) v))))))))))
(define mr-namespace (define mr-namespace (current-namespace))
(if mred?
((dynamic-require '(lib "mred.ss" "mred") 'make-namespace-with-mred))
(let ([ns (make-namespace)])
(namespace-attach-module (current-namespace)
'(lib "struct.ss" "scribble")
ns)
(namespace-attach-module (current-namespace)
'(lib "exn.ss" "scribblings" "quick")
ns)
ns)))
(define image-counter 0) (define image-counter 0)
(define (ss:pict?)
(with-handlers ([exn:fail? (lambda (x) (lambda (x) #f))])
(eval 'pict? mr-namespace)))
(define (ss:pict-width)
(eval 'pict-width mr-namespace))
(define (ss:pict-height)
(eval 'pict-height mr-namespace))
(define (ss:make-pict-drawer)
(eval 'make-pict-drawer mr-namespace))
(define (ss:colorize)
(eval 'colorize mr-namespace))
(define (mred:canvas%)
(dynamic-require '(lib "mred.ss" "mred") 'canvas%))
(define (mred:bitmap%)
(dynamic-require '(lib "mred.ss" "mred") 'bitmap%))
(define (mred:bitmap-dc%)
(dynamic-require '(lib "mred.ss" "mred") 'bitmap-dc%))
(define (fixup-picts v) (define (fixup-picts v)
(cond (cond
[((ss:pict?) v) [(pict? v)
(let ([fn (format "~a/img~a.png" img-dir image-counter)]) (let ([fn (format "~a/img~a.png" img-dir image-counter)])
(set! image-counter (add1 image-counter)) (set! image-counter (add1 image-counter))
(let* ([bm (make-object (mred:bitmap%) (let* ([bm (make-object bitmap%
(inexact->exact (ceiling ((ss:pict-width) v))) (inexact->exact (ceiling (pict-width v)))
(inexact->exact (ceiling ((ss:pict-height) v))))] (inexact->exact (ceiling (pict-height v))))]
[dc (make-object (mred:bitmap-dc%) bm)]) [dc (make-object bitmap-dc% bm)])
(send dc set-smoothing 'aligned) (send dc set-smoothing 'aligned)
(send dc clear) (send dc clear)
(((ss:make-pict-drawer) v) dc 0 0) ((make-pict-drawer (colorize v (make-object color% 0 0 #xAF))) dc 0 0)
(send bm save-file fn 'png) (send bm save-file fn 'png)
(make-element #f (list (make-element (make-image-file fn) (list "[image]"))))))] (make-element #f (list (make-element (make-image-file fn) (list "[image]"))))))]
[(pair? v) (cons (fixup-picts (car v)) [(pair? v) (cons (fixup-picts (car v))

View File

@ -7,9 +7,16 @@
@require[(lib "manual.ss" "scribble")] @require[(lib "manual.ss" "scribble")]
@require["mreval.ss"] @require["mreval.ss"]
@require[(lib "urls.ss" "scribble")] @require[(lib "urls.ss" "scribble")]
@require[(lib "class.ss")]
@require["slideshow-doc.ss"]
@require["slideshow-code-doc.ss"]
@require["mred-doc.ss"]
@require-for-syntax[mzscheme]
@mr-interaction-eval[(require (lib "slideshow.ss" "slideshow"))] @define[filled-flash (lambda args (apply (eval 'filled-flash) args))]
@mr-interaction-eval[(require-for-syntax mzscheme)] @define[random-gaussian (lambda args (apply (eval 'random-gaussian) args))]
@define-syntax[code (syntax-rules () [(_ v) (typeset-code (quote-syntax v))])]
@provide[filled-flash random-gaussian code]
@; ---------------------------------------------------------------------- @; ----------------------------------------------------------------------
@section{Why Pictures? Why DrScheme?} @section{Why Pictures? Why DrScheme?}

View File

@ -0,0 +1,18 @@
(module slideshow-code-doc mzscheme
(require (only "slideshow-doc.ss"))
(define mr-eval? (getenv "MREVAL"))
(define-syntax bounce
(syntax-rules ()
[(_ id)
(begin
(provide id)
(define id (if mr-eval?
(dynamic-require '(lib "code.ss" "slideshow") 'id)
#f)))]
[(_ id ...)
(begin (bounce id) ...)]))
(bounce typeset-code))

View File

@ -0,0 +1,30 @@
(module slideshow-doc mzscheme
(define mr-eval? (getenv "MREVAL"))
(when mr-eval?
(parameterize ([current-command-line-arguments #()])
(dynamic-require '(lib "slideshow.ss" "slideshow") #f)))
(define-syntax bounce
(syntax-rules ()
[(_ id)
(begin
(provide id)
(define id (if mr-eval?
(dynamic-require '(lib "slideshow.ss" "slideshow") 'id)
#f)))]
[(_ id ...)
(begin (bounce id) ...)]))
(bounce circle
rectangle
hc-append
filled-rectangle
vc-append
colorize
scale
bitmap
make-pict-drawer
pict? pict-width pict-height))

View File

@ -1,7 +1,6 @@
#reader(lib "docreader.ss" "scribble") #reader(lib "docreader.ss" "scribble")
@require["mz.ss"] @require["mz.ss"]
@require[(lib "for.ss")]
@interaction-eval[(require (lib "for.ss"))]
@title[#:tag "mz:for"]{Iterations and Comprehensions: @scheme[for], @scheme[for/list], ...} @title[#:tag "mz:for"]{Iterations and Comprehensions: @scheme[for], @scheme[for/list], ...}

View File

@ -497,11 +497,13 @@ forms. As a result, future references of the @tech{variable} always
access the same @tech{location}. access the same @tech{location}.
@;------------------------------------------------------------------------ @;------------------------------------------------------------------------
@section{Modules and Module-Level Variables} @section[#:tag "mz:module-eval-model"]{Modules and Module-Level Variables}
Most definitions in PLT Scheme are in modules. In terms of evaluation, Most definitions in PLT Scheme are in modules. In terms of evaluation,
a module is essentially a prefix on a defined name, so that different a module is essentially a prefix on a defined name, so that different
modules can define the name. modules can define the name. That is, a @deftech{module-level
variable} is like a @tech{top-level variable} from the perspective of
evaluation.
One difference between a module an a top-level definition is that a One difference between a module an a top-level definition is that a
module can be declared without instantiating its module-level module can be declared without instantiating its module-level
@ -621,7 +623,7 @@ is created) as all other threads.
@;------------------------------------------------------------------------ @;------------------------------------------------------------------------
@section{Parameters} @section{Parameters}
A @deftech{parameter} is essentially a derived concept in Scheme; they @deftech{Parameters} are essentially a derived concept in Scheme; they
are defined in terms of continuation marks and thread cells. However, are defined in terms of continuation marks and thread cells. However,
parameters are also built in, in the sense that some primitive parameters are also built in, in the sense that some primitive
procedures consult parameter values. For example, the default output procedures consult parameter values. For example, the default output

View File

@ -5,8 +5,6 @@
(lib "decode.ss" "scribble") (lib "decode.ss" "scribble")
(lib "kw.ss")) (lib "kw.ss"))
(interaction-eval (require (lib "new-lambda.ss" "scribblings")))
(provide (all-from (lib "manual.ss" "scribble")) (provide (all-from (lib "manual.ss" "scribble"))
(all-from (lib "eval.ss" "scribble"))) (all-from (lib "eval.ss" "scribble")))

View File

@ -19,8 +19,8 @@
Scheme's reader is a recursive-descent parser that can be configured Scheme's reader is a recursive-descent parser that can be configured
through a @seclink["mz:readtables"]{readtable} and various other through a @seclink["mz:readtables"]{readtable} and various other
@seclink["parameters"]{parameters}. This section describes the reader's @tech{parameters}. This section describes the reader's parsing when
parsing when using the default readtable. using the default readtable.
Reading from a stream produces one @defterm{datum}. If the result Reading from a stream produces one @defterm{datum}. If the result
datum is a compound value, then reading the datum typically requires datum is a compound value, then reading the datum typically requires
@ -28,7 +28,7 @@ the reader to call itself recursively to read the component data.
The reader can be invoked in either of two modes: @scheme[read] mode, The reader can be invoked in either of two modes: @scheme[read] mode,
or @scheme[read-syntax] mode. In @scheme[read-syntax] mode, the result or @scheme[read-syntax] mode. In @scheme[read-syntax] mode, the result
is always a @seclink["stxobj"]{syntax object} that includes is always a @techlink{syntax object} that includes
source-location and (initially empty) lexical information wrapped source-location and (initially empty) lexical information wrapped
around the sort of datum that @scheme[read] mode would produce. In the around the sort of datum that @scheme[read] mode would produce. In the
case of pairs, vectors, and boxes, morever, the content is also case of pairs, vectors, and boxes, morever, the content is also
@ -164,7 +164,7 @@ except that @litchar{.} by itself is never parsed as a symbol or
character. A @as-index{@litchar{#%}} also starts a symbol. A successful character. A @as-index{@litchar{#%}} also starts a symbol. A successful
number parse takes precedence over a symbol parse. number parse takes precedence over a symbol parse.
When the @scheme[read-case-sensitive] parameter is set to @scheme[#f], When the @scheme[read-case-sensitive] @tech{parameter} is set to @scheme[#f],
characters in the sequence that are not quoted by @litchar["|"] or characters in the sequence that are not quoted by @litchar["|"] or
@litchar["\\"] are first case-normalized. If the reader encounters @litchar["\\"] are first case-normalized. If the reader encounters
@as-index{@litchar{#ci}}, @litchar{#CI}, @litchar{#Ci}, or @litchar{#cI}, @as-index{@litchar{#ci}}, @litchar{#CI}, @litchar{#Ci}, or @litchar{#cI},
@ -202,7 +202,7 @@ which specifies its parsing as an exact or inexact number; see
non-terminal names suggest, a number that has no exactness specifier non-terminal names suggest, a number that has no exactness specifier
and matches only @nunterm{inexact-number} is normally parsed as an and matches only @nunterm{inexact-number} is normally parsed as an
inexact number, otherwise it is parsed as an excat number. If the inexact number, otherwise it is parsed as an excat number. If the
@scheme[read-decimal-as-inexact] parameter is set to @scheme[#f], then @scheme[read-decimal-as-inexact] @tech{parameter} is set to @scheme[#f], then
all numbers without an exactness specifier are instead parsed as all numbers without an exactness specifier are instead parsed as
exact. exact.
@ -344,10 +344,10 @@ being parsed, then the @exnraise[exn:fail:read].
"(1 . 2 . 3)" "(1 . 2 . 3)"
] ]
If the @scheme[read-square-bracket-as-paren] parameter is set to If the @scheme[read-square-bracket-as-paren] @tech{parameter} is set to
@scheme[#f], then when then reader encounters @litchar{[} and @scheme[#f], then when then reader encounters @litchar{[} and
@litchar{]}, the @exnraise{exn:fail:read}. Similarly, If the @litchar{]}, the @exnraise{exn:fail:read}. Similarly, If the
@scheme[read-curly-brace-as-paren] parameter is set to @scheme[#f], @scheme[read-curly-brace-as-paren] @tech{parameter} is set to @scheme[#f],
then when then reader encounters @litchar["{"] and @litchar["}"], the then when then reader encounters @litchar["{"] and @litchar["}"], the
@exnraise{exn:fail:read}. @exnraise{exn:fail:read}.
@ -701,7 +701,7 @@ external reader procedure and applies it to the current input stream.
The reader recursively reads the next datum after @litchar{#reader}, The reader recursively reads the next datum after @litchar{#reader},
and passes it to the procedure that is the value of the and passes it to the procedure that is the value of the
@scheme[current-reader-guard] parameter; the result is used as a @scheme[current-reader-guard] @tech{parameter}; the result is used as a
module path. The module path is passed to @scheme[dynamic-require] module path. The module path is passed to @scheme[dynamic-require]
with either @scheme['read] or @scheme['read-syntax] (depending on with either @scheme['read] or @scheme['read-syntax] (depending on
whether the reader is in @scheme[read] or @scheme[read-syntax] whether the reader is in @scheme[read] or @scheme[read-syntax]
@ -718,7 +718,7 @@ converted to one using @scheme[datum->syntax-object]. See also
@secref["special-comments"] and @secref["recursive-reads"] for @secref["special-comments"] and @secref["recursive-reads"] for
information on special-comment results and recursive reads. information on special-comment results and recursive reads.
If the @scheme[read-accept-reader] parameter is set to @scheme[#f], If the @scheme[read-accept-reader] @tech{parameter} is set to @scheme[#f],
then if the reader encounters @litchar{#reader}, the then if the reader encounters @litchar{#reader}, the
@exnraise[exn:fail:read]. @exnraise[exn:fail:read].

View File

@ -1,10 +1,9 @@
(module reader-example mzscheme (module reader-example (lib "new-lambda.ss" "scribblings")
(require (lib "struct.ss" "scribble") (require (lib "struct.ss" "scribble")
(lib "decode.ss" "scribble") (lib "decode.ss" "scribble")
(lib "manual.ss" "scribble") (lib "manual.ss" "scribble")
(lib "scheme.ss" "scribble") (lib "scheme.ss" "scribble")
(lib "kw.ss")
(lib "class.ss")) (lib "class.ss"))
(provide reader-examples (provide reader-examples
@ -22,10 +21,9 @@
(define spacer (hspace 1)) (define spacer (hspace 1))
(define/kw (reader-examples #:key (define (reader-examples #:symbols? [symbols? #t]
[symbols? #t] #:example-note [example-note ""]
[example-note ""] . strs)
#:body strs)
(make-table (make-table
#f #f
(list (list
@ -125,7 +123,7 @@
(define (dispatch a . b) (define (dispatch a . b)
(list a (make-element #f (decode-content b)))) (list a (make-element #f (decode-content b))))
(define/kw (metavar #:body s) (define (metavar . s)
(make-element 'italic (decode-content s))) (make-element 'italic (decode-content s)))
(define (cilitchar s) (define (cilitchar s)

View File

@ -308,9 +308,9 @@ things:
identifier (third case in the previous enumeration), and identifier (third case in the previous enumeration), and
parsing continues.} parsing continues.}
@item{A core syntactic form, which is parsed as described for each @item{A core @deftech{syntactic form}, which is parsed as described
form in @secref["mz:syntax"]. Parsing a core syntactic form for each form in @secref["mz:syntax"]. Parsing a core syntactic
typically involves recursive parsing of sub-forms, and may form typically involves recursive parsing of sub-forms, and may
introduce @tech{bindings} that determine the parsing of introduce @tech{bindings} that determine the parsing of
sub-forms.} sub-forms.}
@ -340,7 +340,7 @@ contexts. The possible @tech{contexts} are as follows:
@item{@deftech{internal-definition context} : in a nested context that allows @item{@deftech{internal-definition context} : in a nested context that allows
both definitions and expressions.} both definitions and expressions.}
@item{@deftech{expression content} : in a context where only @item{@deftech{expression context} : in a context where only
expressions are allowed.} expressions are allowed.}
} }
@ -440,10 +440,10 @@ be @tech{expand}ed (i.e. parsed) before it can be evaluated, and it is
expanded at @tech{phase level} 1 instead of @tech{phase level} 0. expanded at @tech{phase level} 1 instead of @tech{phase level} 0.
The if resulting @scheme[value] is a procedure of one argument, then The if resulting @scheme[value] is a procedure of one argument, then
is it used as a @deftech{transformer procedure}. The procedure is is it used as a @deftech{syntax transformer}. The procedure is
expected to accept a syntax object and return a syntax object. A use expected to accept a syntax object and return a syntax object. A use
of the binding (at @tech{phase level} 0) triggers a call of the of the binding (at @tech{phase level} 0) triggers a call of the
@tech{transformer procedure} by the expander; see @tech{syntax transformer} by the expander; see
@secref["mz:expand-steps"]. @secref["mz:expand-steps"].
Before the expander passes a @tech{syntax object} to a transformer, Before the expander passes a @tech{syntax object} to a transformer,
@ -547,7 +547,7 @@ If the last expression form turns out to be a @scheme[define-values]
or @scheme[define-syntaxes] form, expansion fails with a syntax error. or @scheme[define-syntaxes] form, expansion fails with a syntax error.
@;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@subsection{Module Phases} @subsection[#:tag "mz:mod-parse"]{Module Phases}
A @scheme[require] form not only introduces @tech{bindings} at A @scheme[require] form not only introduces @tech{bindings} at
expansion time, but also @deftech{visits} the referenced module when expansion time, but also @deftech{visits} the referenced module when

View File

@ -50,6 +50,48 @@ Within such specifications,
}} } }} }
@;------------------------------------------------------------------------
@section{Literals: @scheme[quote] and @scheme[#%datum]}
@defform[(quote datum)]{
Produces a constant value corresponding to @scheme[datum] (i.e., the
actual representation of the program fragment) without its
@tech{lexical information} or source location.
@examples[
(eval:alts (#,(schemekeywordfont "quote") x) 'x)
(eval:alts (#,(schemekeywordfont "quote") (+ 1 2)) '(+ 1 2))
]
}
@defform[(#%datum . datum)]{
Expands to @scheme[(#,(schemekeywordfont "quote") datum)]. See also @secref["mz:expand-steps"]
for information on how the expander introduces @schemeidfont{#%datum}
identifiers.
@examples[
(#%datum . 10)
(#%datum . x)
]
}
@;------------------------------------------------------------------------
@section{Expression Wrapper: @scheme[#%expression]}
@defform[(#%expression expr)]{
Produces the same result as @scheme[expr]. The only use of
@scheme[#%expression] is to force the parsing of a form as an
expression.
@examples[
(#%expression (+ 1 2))
(#%expression (define x 10))
]}
@;------------------------------------------------------------------------ @;------------------------------------------------------------------------
@section{Variable References and @scheme[#%top]} @section{Variable References and @scheme[#%top]}
@ -64,7 +106,7 @@ When the expander encounters an @scheme[id] that is not bound by a
module-level or local binding, it converts the expression to @scheme[(#, module-level or local binding, it converts the expression to @scheme[(#,
@schemeidfont{#%top} . id)] giving @schemeidfont{#%top} the lexical @schemeidfont{#%top} . id)] giving @schemeidfont{#%top} the lexical
context of the @scheme[id]; typically, that context refers to context of the @scheme[id]; typically, that context refers to
@scheme[#%top]. @scheme[#%top]. See also @secref["mz:expand-steps"].
@examples[ @examples[
(define x 10) (define x 10)
@ -75,15 +117,31 @@ x
@defform[(#%top . id)]{ @defform[(#%top . id)]{
Refers to a top-level definition that could bind @scheme[id], Refers to a top-level definition that could bind @scheme[id], even if
even if @scheme[id] has a local binding in its context. Such @scheme[id] has a local binding in its context. Such references are
references are disallowed anywhere within a @scheme[module] form. disallowed anywhere within a @scheme[module] form. See also
@secref["mz:expand-steps"] for information on how the expander
introduces @schemeidfont{#%top} identifiers.
@examples[ @examples[
(define x 12) (define x 12)
(let ([x 5]) (#%top . x)) (let ([x 5]) (#%top . x))
]} ]}
@;------------------------------------------------------------------------
@section{Locations: @scheme[#%variable-reference]}
@defform*[#:literals (#%top)
[(#%variable-reference id)
(#%variable-reference (#%top . id))]]{
Produces an opaque value representing the location of @scheme[id],
which must be bound as a @tech{top-level variable} or
@tech{module-level variable}.
The result is useful only to low-level extensions; see
@secref["inside-mzscheme"].}
@;------------------------------------------------------------------------ @;------------------------------------------------------------------------
@section[#:tag "mz:application"]{Procedure Applications and @scheme[#%app]} @section[#:tag "mz:application"]{Procedure Applications and @scheme[#%app]}
@ -100,7 +158,8 @@ More precisely, the expander converts this form to @scheme[(#,
the lexical context that is associated with the original form (i.e., the lexical context that is associated with the original form (i.e.,
the pair that combines @scheme[proc-expr] and its the pair that combines @scheme[proc-expr] and its
arguments). Typically, the lexical context of the pair indicates the arguments). Typically, the lexical context of the pair indicates the
procedure-application @scheme[#%app] that is described next. procedure-application @scheme[#%app] that is described next. See also
@secref["mz:expand-steps"].
@examples[ @examples[
(+ 1 2) (+ 1 2)
@ -138,6 +197,9 @@ the @scheme[_keyword]s, and not their positions. The other
@scheme[_arg-expr] values, in contrast, are associated with variables @scheme[_arg-expr] values, in contrast, are associated with variables
according to their order in the application form. according to their order in the application form.
See also @secref["mz:expand-steps"] for information on how the
expander introduces @schemeidfont{#%app} identifiers.
@examples[ @examples[
(#%app + 1 2) (#%app + 1 2)
(#%app (lambda (x #:arg y) (list y x)) #:arg 2 1) (#%app (lambda (x #:arg y) (list y x)) #:arg 2 1)
@ -442,8 +504,8 @@ using the @|cvt| meta-function defined as follows:
At the top level, the top-level binding @scheme[id] is created after At the top level, the top-level binding @scheme[id] is created after
evaluating @scheme[expr], if it does not exist already, and the evaluating @scheme[expr], if it does not exist already, and the
top-level mapping of @scheme[id] (see @secref["mz:namespace"]) is set top-level mapping of @scheme[id] (in the @techlink{namespace} linked
to the binding at the same time. with the compiled definition) is set to the binding at the same time.
@defexamples[ @defexamples[
(define x 10) (define x 10)
@ -472,8 +534,9 @@ the @exnraise[exn:fail:contract].
At the top level, the top-level binding for each @scheme[id] is At the top level, the top-level binding for each @scheme[id] is
created after evaluating @scheme[expr], if it does not exist already, created after evaluating @scheme[expr], if it does not exist already,
and the top-level mapping of each @scheme[id] (see and the top-level mapping of each @scheme[id] (in the
@secref["mz:namespace"]) is set to the binding at the same time. @techlink{namespace} linked with the compiled definition) is set to
the binding at the same time.
@defexamples[ @defexamples[
(define-values () (values)) (define-values () (values))
@ -526,6 +589,42 @@ in tail position only if no @scheme[body]s are present.
(printf "hi\n")) (printf "hi\n"))
]} ]}
@;------------------------------------------------------------------------
@section{Assignment: @scheme[set!] and @scheme[set!-values]}
@defform[(set! id expr)]{
Evaluates @scheme[expr] and installs the result into the location for
@scheme[id], which must be bound as a local variable or defined as a
@tech{top-level variable} or @tech{module-level variable}. If
@scheme[id] refers to a @tech{top-level variable} that has not been
defined, the @exnraise[exn:fail:contract].
@defexamples[
(define x 12)
(set! x (add1 x))
x
(let ([x 5])
(set! x (add1 x))
x)
(set! i-am-not-defined 10)
]}
@defform[(set!-values (id ...) expr)]{
Evaluates @scheme[expr], which must produce as many values as supplied
@scheme[id]s. The location of each @scheme[id] is filled wih to the
corresponding value from @scheme[expr] in the same way as for
@scheme[set!].
@examples[
(let ([a 1]
[b 2])
(set!-values (a b) (values b a))
(list a b))
]}
@;------------------------------------------------------------------------ @;------------------------------------------------------------------------
@section{Continuation Marks: @scheme[with-continuation-mark]} @section{Continuation Marks: @scheme[with-continuation-mark]}
@ -540,11 +639,196 @@ current continuation frame (see @secref["mz:contmarks"]), and then
@section{Syntax Quoting: @scheme[quote-syntax]} @section{Syntax Quoting: @scheme[quote-syntax]}
@defform[(quote-syntax datum)]{ @defform[(quote-syntax datum)]{
Produces a syntax object that preserves
lexical and source-location information attached to @scheme[datum] Produces a @tech{syntax object} that preserves the @tech{lexical
at expansion time. information} and source-location information attached to
@scheme[datum] at expansion time.
@examples[ @examples[
(syntax? (quote-syntax x)) (syntax? (quote-syntax x))
] ]
} }
@;------------------------------------------------------------------------
@section[#:tag "mz:require"]{Importing: @scheme[require], @scheme[require-for-syntax], @scheme[require-for-template]}
@defform/subs[#:literals (only prefix all-except prefix-all-except rename lib file planet)
(require require-spec ...)
([require-spec module-path
(only require-spec id-maybe-renamed ...)
(except require-spec id ...)
(prefix require-spec prefix-id)
(rename require-spec [orig-id bind-id] ...)]
[module-path id
rel-string
(lib rel-string)
(file string)
(planet rel-string (user-string pkg-string vers ...))]
[id-maybe-renamed id
[orig-id bind-id]]
[vers nat
(nat nat)
(= nat)
(+ nat)
(- nat)])]{
In a @tech{top-level context}, @scheme[require] instantiates modules
(see @secref["mz:module-eval-model"]). In a @tech{module context},
@scheme[require] visits modules (see @secref["mz:mod-parse"]). In both
contexts, @scheme[require] introduces bindings into a @tech{namespace}
or a module (see @secref["mz:intro-binding"]). A @scheme[require] form
in a @tech{expression context} or @tech{internal-definition context}
is a syntax error.
A @scheme[require-spec] designates a particular set of identifiers to
be bound in the importing context. Each identifier is mapped to a
particular export of a particular module; the identifier to bind may
be different from the symbolic name of the originally exported
identifier.
@specsubform[module-path]{ Imports all exported bindings from the
named module, using the export identifier as the local identifiers.}
@specsubform[#:literals (only) (only require-spec id-maybe-renamed ...)]{
Like @scheme[require-spec], but constrained to those exports for
which the identifiers to bind match @scheme[id-maybe-renamed]: as
@scheme[id] or as @scheme[orig-id] in @scheme[[orig-id bind-id]]. If
the @scheme[id] of @scheme[orig-id] of any @scheme[id-maybe-renamed]
is not in the set that @scheme[require-spec] describes, a syntax
error is reported.}
@specsubform[#:literals (except) (except require-spec id ...)]{ Like
@scheme[require-spec], but omitting those exports for which
@scheme[id]s are the identifiers to bind; if any @scheme[id] is not
in the set that @scheme[require-spec] describes, a syntax error is
reported.}
@specsubform[#:literals (prefix) (prefix require-spec prefix-id)]{
Like @scheme[require-spec], but adjusting each identifier to be bound
by prefixing it with @scheme[prefix-id].}
@specsubform[#:literals (rename)
(rename require-spec [orig-id bind-id] ...)]{
Like @scheme[require-spec], but replacing the identifier to
bind @scheme[orig-id] with @scheme[bind-id]; if any
@scheme[orig-id] is not in the set that @scheme[require-spec]
describes, a syntax error is reported.}
A @scheme[module-path] identifies a module, either through a concrete
name in the form of an identifier, or through an indirect name that
can trigger automatic loading of the module declaration:
@specsubform[id]{ Refers to a module previously declared with the name
@scheme[id].}
@specsubform[rel-string]{A path relative to the containing source (as
determined by @scheme[current-load-relative-directory] or
@scheme[current-directory]). Regardless of the current platform,
@scheme[rel-string] is always parsed as a Unix-format relative path:
@litchar{/} is the path delimiter (multiple adjacent @litchar{/}s are
treated as a single delimiter), @litchar{..} accesses the parent
directory, and @litchar{.} accesses the current directory. The path
cannot be empty or contain a leading or trailing slash.}
@specsubform[#:literals (lib) (lib rel-string)]{Like the plain
@scheme[rel-string] case, but @scheme[rel-string] must contain at
least two path elements. All path elements up to the last one form a
@tech{collection} path, which is used to locate the relevant
directory (not relative to the containing source), and the last path
element refers to a file.}
@specsubform[#:literals (file) (file string)]{Similar to the plain
@scheme[rel-string] case, but @scheme[string] is a path (possibly
absolute) using the current platform's path conventions.}
@specsubform[#:literals(planet)
(planet rel-string (user-string pkg-string vers ...))]{
Specifies a library available via the @PLaneT server.
}
No identifier can be bound multiple times by an import, unless all of
the bindings refer to the same original definition in the same module.
In a @tech{module context}, an identifier can be either imported or
defined for a given @tech{phase level}, but not both.}
@defform[(require-for-syntax require-spec ...)]{
Like @scheme[require], but @tech{instantiate}s a module at phase 1
(see @secref["mz:module-eval-model"]) in a @tech{top-level context} or
@tech{module context}, and introduces bindings at phase level 1 (see
@secref["mz:intro-binding"] and @secref["mz:mod-parse"]).
}
@defform[(require-for-template require-spec ...)]{ Like
@scheme[require], but without @tech{instantiation} (see
@secref["mz:module-eval-model"]) in a @tech{top-level context}, and
introduces bindings at phase level -1 (see @secref["mz:intro-binding"]
and @secref["mz:mod-parse"]).
}
@;------------------------------------------------------------------------
@section{Exporting: @scheme[provide] and @scheme[provide-for-syntax]}
@defform/subs[#:literals (protect all-defined all-from rename except prefix)
(provide protected-provide-spec ...)
([protected-provide-spec provide-spec
(protect provide-spec)]
[provide-spec id
(all-defined)
(all-from module-name)
(rename [orig-id export-id] ...)
(except provide-spec id ...)
(prefix provide-spec prefix-id)])]{
Declares exports from a module. A @scheme[provide] form must appear in
a @tech{module context} or a @tech{module-begin} context.
A @scheme[provide-spec] indicates one or more bindings to provide,
specifying for each an export symbol that can be different from
the symbolic form of the identifier bound within the module:
@specsubform[id]{ Exports @scheme[id], which must be @tech{bound}
within the module (i.e., either defined or imported), at @tech{phase
level} 0 using the symbolic form of @scheme[id] as the external
name.}
@specsubform[#:literals (all-defined) (all-defined)]{ Exports all
identifiers that are defined at @tech{phase level} 0 within the
exporting module. The external name for each identifier is the
symbolic form of the identifier; note that this can lead to an
illegal multiple export for a single symbolic name if different
defined identifiers use the same symbolic name.}
@specsubform[#:literals (all-from) (all-from module-name)]{ Exports
all identifiers that are imported into the exporting module at
@tech{phase level} 0 using a @scheme[require-spec] built on
@scheme[module-name] (see @secref["mz:require"]). The symbolic name
for export is derived from the name that is bound within the module,
as opposed to the symbolic name of the export from
@scheme[module-name].}
@specsubform[#:literals (rename) (rename [orig-id export-id] ...)]{
Exports each @scheme[orig-id], which must be @tech{bound} within the
module at @tech{phase level} 0. The symbolic name for each export is
@scheme[export-id] instead @scheme[orig-d].}
@specsubform[#:literals (except) (except provide-spec id ...)]{ Like
@scheme[provide-spec], but omitting an export for each binding
@scheme[id]. If @scheme[id] is not specified as an export by
@scheme[provide-spec], a syntax error is reported.}
@specsubform[#:literals (prefix) (prefix provide-spec prefix-id)]{
Like @scheme[provide-spec], but with each symbolic export name from
@scheme[provide-spec] prefixed with @scheme[prefix-id].}
If @scheme[provide] wraps a @scheme[provide-spec], then the exports of
the @scheme[provide-spec] are protected; see
@secref["mz:protected-exports"]. The @scheme[provide-spec] must
specify only bindings that are defined within the exporting module.
Each export specified within a module must have a distinct symbolic
export name, though the same binding can be specified with the
multiple symbolic names.}
@defform[(provide-for-syntax protected-provide-spec ...)]{Like
@scheme[provide], but exports at @tech{phase level} 1 bindings within
the module at @tech{phase level} 1.}

View File

@ -10,24 +10,24 @@ especially to show example uses of defined procedures and syntax.
@defform[(interaction datum ...)]{Like @scheme[schemeinput], except @defform[(interaction datum ...)]{Like @scheme[schemeinput], except
that the result for each input @scheme[datum] is shown on the next that the result for each input @scheme[datum] is shown on the next
line. The result is determined by evaluating the quoted form of the line. The result is determined by evaluating the syntax-quoted form of
datum. the @scheme[datum].
Uses of @scheme[code:comment] and @schemeidfont{code:blank} are Uses of @scheme[code:comment] and @schemeidfont{code:blank} are
stipped from each @scheme[datum] before evaluation. stipped from each @scheme[datum] before evaluation.
If a datum has the form @scheme[(#,(scheme code:line) #,(svar datum) If a @scheme[datum] has the form @scheme[(#,(scheme code:line)
(#,(scheme code:comment) ...))], then only the @svar[datum] is _code-datum (#,(scheme code:comment) ...))], then only
evaluated. @scheme[_code-datum] is evaluated.
If a datum has the form @scheme[(eval:alts #,(svar show-datum) #,(svar If a datum has the form @scheme[(eval:alts #,(svar show-datum) #,(svar
eval-datum))], then @svar[show-datum] is typeset, while eval-datum))], then @svar[show-datum] is typeset, while
@svar[eval-datum] is evaluated.} @svar[eval-datum] is evaluated.}
@defform[(interaction-eval datum)]{Evaluates the quoted form of @defform[(interaction-eval datum)]{Evaluates the syntax-quoted form of
each @scheme[datum] via @scheme[do-eval] and returns the empty string.} each @scheme[datum] via @scheme[do-eval] and returns the empty string.}
@defform[(interaction-eval-show datum)]{Evaluates the quoted form of @defform[(interaction-eval-show datum)]{Evaluates the syntax-quoted form of
@scheme[datum] and produces an element represeting the printed form of @scheme[datum] and produces an element represeting the printed form of
the result.} the result.}

View File

@ -14,7 +14,7 @@ more...
@defform[(schemeblock datum ...)]{ @defform[(schemeblock datum ...)]{
Typesets the @scheme[datum] sequence as a table of Scheme code inset Typesets the @scheme[datum] sequence as a table of Scheme code inset
by two spaces. The source locations of the @scheme[datum]s determines by two spaces. The source locations of the @scheme[datum]s determine
the generated layout. For example, the generated layout. For example,
@schemeblock[ @schemeblock[
@ -32,10 +32,13 @@ produces the output
with the @scheme[(loop (not x))] indented under @scheme[define], with the @scheme[(loop (not x))] indented under @scheme[define],
because that's the way it is idented the use of @scheme[schemeblock]. because that's the way it is idented the use of @scheme[schemeblock].
Furthermore, @scheme[define] is typeset as a keyword (bold and black) Furthermore, @scheme[define] is typeset as a keyword (bold and black)
and as a hyperlink to @scheme[define]'s definition in the reference and as a hyperlink to @scheme[define]'s definition in the reference
manual, because this document was built using information about the manual, because this document was built using information about the
MzScheme manual. Similarly, @scheme[not] is a hyperlink to the its reference manual, and because the lexical binding of @scheme[define]
(in the source) matches the lexical binding of the definition in the
reference manual. Similarly, @scheme[not] is a hyperlink to the its
definition in the reference manual. definition in the reference manual.
Use @scheme[unsyntax] to escape back to an expression that produces an Use @scheme[unsyntax] to escape back to an expression that produces an
@ -127,7 +130,7 @@ useful with @scheme[verbatim].}
@defproc[(schemefont [pre-content any/c] ...) element?]{Typesets the given @defproc[(schemefont [pre-content any/c] ...) element?]{Typesets the given
content as uncolored, unhyperlinked Scheme. This procedure is useful content as uncolored, unhyperlinked Scheme. This procedure is useful
for typesetting thngs like @scheme{#module}, which are not for typesetting things like @scheme{#module}, which are not
@scheme[read]able by themselves.} @scheme[read]able by themselves.}
@defproc[(schemevalfont [pre-content any/c] ...) element?]{Like @defproc[(schemevalfont [pre-content any/c] ...) element?]{Like
@ -143,7 +146,7 @@ for typesetting thngs like @scheme{#module}, which are not
@scheme[schemefont], but colored as a syntactic form name.} @scheme[schemefont], but colored as a syntactic form name.}
@defproc[(procedure [pre-content any/c] ...) element?]{Typesets the given @defproc[(procedure [pre-content any/c] ...) element?]{Typesets the given
content as a procedure name in a REPL result (e.g., in typewrite font content as a procedure name in a REPL result (e.g., in typewriter font
with a @schemefont{#<procedure:} prefix and @schemefont{>} suffix.).} with a @schemefont{#<procedure:} prefix and @schemefont{>} suffix.).}
@defform[(var datum)]{Typesets @scheme[var] as an identifier that is @defform[(var datum)]{Typesets @scheme[var] as an identifier that is
@ -164,9 +167,9 @@ in a form definition.}
pre-flow ...)]{ pre-flow ...)]{
Produces a sequence of flow elements (encaptured in a @scheme[splice]) Produces a sequence of flow elements (encaptured in a @scheme[splice])
to document a procedure named @scheme[id]. The to document a procedure named @scheme[id]. The @scheme[id] is
@scheme[id] is registered so that @scheme[scheme]-typeset uses registered so that @scheme[scheme]-typeset uses of the identifier
of the identifier are hyperlinked to this documentation. (with the same lexical binding) are hyperlinked to this documentation.
Each @scheme[arg-spec] must have one of the following forms: Each @scheme[arg-spec] must have one of the following forms:
@ -213,39 +216,54 @@ Like @scheme[defproc], but for multiple cases with the same
@scheme[id]. } @scheme[id]. }
@defform[(defform (id . datum) pre-flow ...)]{Produces a @defform/subs[(defform maybe-literals (id . datum) pre-flow ...)
a sequence of flow elements (encaptured in a @scheme[splice]) to ([maybe-literals code:blank
document a syntatic form named by @scheme[id]. The (code:line #:literals (literal-id ...))])]{
@scheme[id] is registered so that @scheme[scheme]-typeset uses
of the identifier are hyperlinked to this documentation. Produces a a sequence of flow elements (encaptured in a
@scheme[splice]) to document a syntatic form named by @scheme[id]. The
@scheme[id] is registered so that @scheme[scheme]-typeset uses of the
identifier (with the same lexical binding) are hyperlinked to this
documentation.
The @scheme[pre-flow]s list is parsed as a flow that documents the The @scheme[pre-flow]s list is parsed as a flow that documents the
procedure. In this description, a reference to any identifier in procedure. In this description, a reference to any identifier in
@scheme[datum] is typeset as a sub-form non-terminal. @scheme[datum] is typeset as a sub-form non-terminal. If
@scheme[#:literals] clause is provided, however, instances of the
@scheme[literal-id]s are typeset normally.
The typesetting of @scheme[(id . datum)] preserves the source The typesetting of @scheme[(id . datum)] preserves the source
layout, like @scheme[schemeblock], and unlike @scheme[defproc].} layout, like @scheme[schemeblock], and unlike @scheme[defproc].}
@defform[(defform* [(id . datum) ..+] pre-flow ...)]{Like @scheme[defform], @defform[(defform* maybe-literals [(id . datum) ..+] pre-flow ...)]{
but for multiple forms using the same @scheme[id].}
@defform[(defform/subs (id . datum) Like @scheme[defform], but for multiple forms using the same
([nonterm-id clause-datum ...+] ...) @scheme[id].}
pre-flow ...)]{
@defform/subs[(defform/subs maybe-literals (id . datum)
([nonterm-id clause-datum ...+] ...)
pre-flow ...)
([maybe-literals code:blank
(code:line #:literals (literal-id ...))])]{
Like @scheme[defform], but including an auxiliary grammar of Like @scheme[defform], but including an auxiliary grammar of
non-terminals shown with the @scheme[id] form. Each non-terminals shown with the @scheme[id] form. Each
@scheme[nonterm-id] is specified as being any of the corresponding @scheme[nonterm-id] is specified as being any of the corresponding
@scheme[clause-datum]s, where the formatting of each @scheme[clause-datum]s, where the formatting of each
@scheme[clause-datum] is preserved.} @scheme[clause-datum] is preserved.}
@defform[(specform (id . datum) pre-flow ...)]{Like @scheme[defform], @defform/subs[(specform maybe-literals (id . datum) pre-flow ...)
with without registering a definition, and with indenting on the left ([maybe-literals code:blank
for both the specification and the @scheme[pre-flow]s.} (code:line #:literals (literal-id ...))])]{
@defform[(specsubform datum pre-flow ...)]{Similar to Like @scheme[defform], with without registering a definition, and with
@scheme[defform], but without any specific identifier being defined, indenting on the left for both the specification and the
and the table and flow are typeset indented. This form is intended for @scheme[pre-flow]s.}
use when refining the syntax of a non-terminal used in a
@defform[(specsubform maybe-literals datum pre-flow ...)]{
Similar to @scheme[defform], but without any specific identifier being
defined, and the table and flow are typeset indented. This form is
intended for use when refining the syntax of a non-terminal used in a
@scheme[defform] or other @scheme[specsubform]. For example, it is @scheme[defform] or other @scheme[specsubform]. For example, it is
used in the documentation for @scheme[defproc] in the itemization of used in the documentation for @scheme[defproc] in the itemization of
possible shapes for @svar[arg-spec]. possible shapes for @svar[arg-spec].
@ -254,8 +272,9 @@ The @scheme[pre-flow]s list is parsed as a flow that documents the
procedure. In this description, a reference to any identifier in procedure. In this description, a reference to any identifier in
@scheme[datum] is typeset as a sub-form non-terminal.} @scheme[datum] is typeset as a sub-form non-terminal.}
@defform[(defthing id contract-expr-datum pre-flow ...)]{Like @defform[(defthing id contract-expr-datum pre-flow ...)]{
@scheme[defproc], but for a non-procedure binding.}
Like @scheme[defproc], but for a non-procedure binding.}
@defform/subs[(defstruct struct-name ([field-name contract-expr-datum] ...) @defform/subs[(defstruct struct-name ([field-name contract-expr-datum] ...)
pre-flow ...) pre-flow ...)
@ -265,13 +284,19 @@ procedure. In this description, a reference to any identifier in
Similar to @scheme[defform] or @scheme[defproc], but for a structure Similar to @scheme[defform] or @scheme[defproc], but for a structure
definition.} definition.}
@defform/subs[(schemegrammar literals ? id clause-datum ...+) @defform/subs[(schemegrammar maybe-literals id clause-datum ...+)
([literals (code:line #:literals (literal-id ...))])]{ ([maybe-literals code:blank
Creates a table to define the grammar of @scheme[id]. Each identifier mentioned (code:line #:literals (literal-id ...))])]{
in a @scheme[clause-datum] is typeset as a non-terminal, except for the
identifiers listed as @scheme[literal-id]s, which are typeset as with Creates a table to define the grammar of @scheme[id]. Each identifier
@scheme[scheme]. mentioned in a @scheme[clause-datum] is typeset as a non-terminal,
} except for the identifiers listed as @scheme[literal-id]s, which are
typeset as with @scheme[scheme].}
@defform[(schemegrammar* maybe-literals [id clause-datum ...+] ...)]{
Like @scheme[schemegrammar], but for typesetting multiple productions
at once, aligned around the @litchar{=} and @litchar{|}.}
@; ------------------------------------------------------------------------ @; ------------------------------------------------------------------------
@section{Various String Forms} @section{Various String Forms}