change scribble to use new-lambda and new-struct, and correlate definitions and uses via lexical binding
svn: r6714
|
@ -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))
|
||||||
|
|
|
@ -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 ----------------------------------------
|
||||||
|
|
|
@ -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 ()
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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
|
||||||
|
(datum->syntax-object stx-id
|
||||||
|
(string->symbol
|
||||||
(apply string-append
|
(apply string-append
|
||||||
(map symbol->string (car wrappers))))))
|
(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,20 +584,23 @@
|
||||||
(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 (apply *schemerawgrammar
|
(list (make-flow (list (let ([l (map (lambda (sub)
|
||||||
(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)
|
||||||
|
@ -610,25 +629,31 @@
|
||||||
(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 (apply *schemerawgrammar
|
(list (make-flow (list (let ([l (map (lambda (sub)
|
||||||
(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)))))])
|
||||||
|
(cdr
|
||||||
(apply append
|
(apply append
|
||||||
(map
|
(map
|
||||||
(lambda (nonterm clauses)
|
(lambda (nonterm clauses)
|
||||||
(cons
|
(list*
|
||||||
|
(list empty-line empty-line empty-line empty-line empty-line)
|
||||||
(list (to-flow nonterm)
|
(list (to-flow nonterm)
|
||||||
empty-line
|
empty-line
|
||||||
(to-flow "=")
|
(to-flow "=")
|
||||||
|
@ -641,10 +666,10 @@
|
||||||
empty-line
|
empty-line
|
||||||
(make-flow (list clause))))
|
(make-flow (list clause))))
|
||||||
(cdr clauses))))
|
(cdr clauses))))
|
||||||
nonterms clauseses)))))
|
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
|
||||||
|
|
|
@ -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)))
|
||||||
|
|
|
@ -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%;
|
||||||
}
|
}
|
||||||
|
|
400
collects/scribblings/guide/class.scrbl
Normal 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}).
|
|
@ -133,7 +133,7 @@ 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)
|
||||||
]
|
]
|
||||||
|
|
|
@ -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]}
|
||||||
|
|
||||||
|
|
|
@ -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}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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"]
|
||||||
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
@; ----------------------------------------------------------------------
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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))
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -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}
|
||||||
|
|
||||||
|
|
|
@ -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}
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
413
collects/scribblings/new-struct.ss
Normal 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)]))))))))])))
|
|
@ -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")
|
||||||
|
|
Before Width: | Height: | Size: 209 B After Width: | Height: | Size: 205 B |
Before Width: | Height: | Size: 102 B After Width: | Height: | Size: 102 B |
Before Width: | Height: | Size: 710 B After Width: | Height: | Size: 658 B |
Before Width: | Height: | Size: 143 B After Width: | Height: | Size: 143 B |
Before Width: | Height: | Size: 209 B After Width: | Height: | Size: 205 B |
Before Width: | Height: | Size: 77 B After Width: | Height: | Size: 77 B |
Before Width: | Height: | Size: 300 B After Width: | Height: | Size: 288 B |
Before Width: | Height: | Size: 837 B After Width: | Height: | Size: 819 B |
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 102 B After Width: | Height: | Size: 102 B |
Before Width: | Height: | Size: 300 B After Width: | Height: | Size: 288 B |
Before Width: | Height: | Size: 388 B After Width: | Height: | Size: 372 B |
Before Width: | Height: | Size: 77 B After Width: | Height: | Size: 77 B |
Before Width: | Height: | Size: 242 B After Width: | Height: | Size: 236 B |
18
collects/scribblings/quick/mred-doc.ss
Normal 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%))
|
|
@ -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))
|
||||||
|
|
|
@ -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?}
|
||||||
|
|
18
collects/scribblings/quick/slideshow-code-doc.ss
Normal 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))
|
||||||
|
|
30
collects/scribblings/quick/slideshow-doc.ss
Normal 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))
|
|
@ -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], ...}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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")))
|
||||||
|
|
||||||
|
|
|
@ -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].
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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.}
|
||||||
|
|
|
@ -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.}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
@scheme[id].}
|
||||||
|
|
||||||
|
@defform/subs[(defform/subs maybe-literals (id . datum)
|
||||||
([nonterm-id clause-datum ...+] ...)
|
([nonterm-id clause-datum ...+] ...)
|
||||||
pre-flow ...)]{
|
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}
|
||||||
|
|