Merge remote branch 'origin/master' into samth/new-logic2

This commit is contained in:
Sam Tobin-Hochstadt 2010-04-23 18:36:46 -04:00
commit b173f70ad1
77 changed files with 3010 additions and 2773 deletions

5
.gitignore vendored
View File

@ -9,3 +9,8 @@
# a common convenient place to set the PLTADDON directory to # a common convenient place to set the PLTADDON directory to
/add-on/ /add-on/
# common backups, autosaves, and lock files
*~
\#*
.#*

View File

@ -20,6 +20,7 @@
lang/posn lang/posn
scheme/gui/base scheme/gui/base
"../../mrlib/image-core.ss" "../../mrlib/image-core.ss"
(prefix-in cis: "../../mrlib/cache-image-snip.ss")
(for-syntax scheme/base (for-syntax scheme/base
scheme/list)) scheme/list))
@ -270,9 +271,26 @@
[else arg])) [else arg]))
(define (image-snip->image is) (define (image-snip->image is)
(bitmap->image (send is get-bitmap) (let ([bm (send is get-bitmap)])
(cond
[(not bm)
;; this might mean we have a cache-image-snip%
;; or it might mean we have a useless snip.
(let-values ([(w h) (if (is-a? is cis:cache-image-snip%)
(send is get-size)
(values 0 0))])
(make-image (make-polygon
(list (make-point 0 0)
(make-point w 0)
(make-point w h)
(make-point 0 h))
'solid "black")
(make-bb w h h)
#f))]
[else
(bitmap->image bm
(or (send is get-bitmap-mask) (or (send is get-bitmap-mask)
(send (send is get-bitmap) get-loaded-mask)))) (send bm get-loaded-mask)))])))
(define (bitmap->image bm [mask-bm (send bm get-loaded-mask)]) (define (bitmap->image bm [mask-bm (send bm get-loaded-mask)])
(let ([w (send bm get-width)] (let ([w (send bm get-width)]

View File

@ -46,6 +46,7 @@
scheme/class scheme/class
scheme/gui/base scheme/gui/base
schemeunit schemeunit
(prefix-in 1: htdp/image)
(only-in lang/htdp-advanced equal~?)) (only-in lang/htdp-advanced equal~?))
(require (for-syntax scheme/base)) (require (for-syntax scheme/base))
@ -202,6 +203,14 @@
(check-close (image-height (rotate 30 (ellipse 0 100 'solid 'blue))) (check-close (image-height (rotate 30 (ellipse 0 100 'solid 'blue)))
(ceiling (* (cos (* pi 1/6)) 100))) (ceiling (* (cos (* pi 1/6)) 100)))
;; zero-sized htdp/image images should also work
(test (image-width (1:text "" 18 "blue"))
=>
0)
(test (image-height (1:rectangle 10 0 'solid "red"))
=>
0)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; polygon equality ;; polygon equality

View File

@ -1,4 +1,4 @@
#lang scheme/base #lang racket/base
(provide get-general-acks (provide get-general-acks
get-translating-acks get-translating-acks

View File

@ -1,4 +1,4 @@
#lang scheme/base #lang racket/base
(require scheme/class (require scheme/class
scheme/math scheme/math

View File

@ -1,4 +1,4 @@
(module default-code-style mzscheme #lang racket/base
(provide color-default-code-styles (provide color-default-code-styles
bw-default-code-styles bw-default-code-styles
code-style-color code-style-color
@ -24,4 +24,4 @@
(list 'unbound-variable (make-code-style "red" #f #f #f)) (list 'unbound-variable (make-code-style "red" #f #f #f))
(list 'bound-variable (make-code-style "navy" #f #f #f)) (list 'bound-variable (make-code-style "navy" #f #f #f))
(list 'primitive (make-code-style "navy" #f #f #f)) (list 'primitive (make-code-style "navy" #f #f #f))
(list 'constant (make-code-style '(51 135 39) #f #f #f))))) (list 'constant (make-code-style '(51 135 39) #f #f #f))))

View File

@ -1,4 +1,4 @@
#lang scheme/base #lang racket/base
(require scheme/gui/base "private/key.ss") (require scheme/gui/base "private/key.ss")
(define debugging? (getenv "PLTDRDEBUG")) (define debugging? (getenv "PLTDRDEBUG"))

View File

@ -1,4 +1,4 @@
(module installer mzscheme #lang racket/base
(require mzlib/file (require mzlib/file
mzlib/etc mzlib/etc
launcher) launcher)
@ -18,4 +18,4 @@
(mred-program-launcher-path "DrScheme") (mred-program-launcher-path "DrScheme")
(cons (cons
`(exe-name . "DrScheme") `(exe-name . "DrScheme")
(build-aux-from-path (build-path (collection-path "drscheme") "drscheme"))))))) (build-aux-from-path (build-path (collection-path "drscheme") "drscheme"))))))

View File

@ -1,2 +1,2 @@
(module main scheme/base #lang racket/base
(require "drscheme.ss")) (require "drscheme.ss")

View File

@ -1,10 +1,8 @@
#lang scheme/unit #lang scheme/unit
(require mzlib/class (require racket/class
mzlib/list
scheme/file
string-constants string-constants
mred racket/gui/base
framework framework
browser/external browser/external
setup/getinfo setup/getinfo

View File

@ -1,4 +1,4 @@
#lang mzscheme #lang racket/base
#| #|
CODE COPIED (with permission ...) from syntax-browser.ss CODE COPIED (with permission ...) from syntax-browser.ss
@ -9,13 +9,10 @@ Marshalling (and hence the 'read' method of the snipclass omitted for fast proto
|# |#
(require mzlib/pretty (require racket/pretty
mzlib/list racket/class
mzlib/class racket/gui/base
mred racket/contract)
mzlib/match
mzlib/string
mzlib/contract)
(provide render-bindings/snip) (provide render-bindings/snip)
@ -64,7 +61,7 @@ Marshalling (and hence the 'read' method of the snipclass omitted for fast proto
; how to enrich the notion of an output-port to get 'bold'ing to ; how to enrich the notion of an output-port to get 'bold'ing to
; work otherwise... ; work otherwise...
(let* ([before (send output-text last-position)]) (let* ([before (send output-text last-position)])
(pretty-print (syntax-object->datum stx)) (pretty-print (syntax->datum stx))
(let* ([post-newline (send output-text last-position)]) (let* ([post-newline (send output-text last-position)])
(send output-text delete post-newline) ; delete the trailing \n. yuck! (send output-text delete post-newline) ; delete the trailing \n. yuck!
(send output-text insert " ") (send output-text insert " ")
@ -164,7 +161,7 @@ Marshalling (and hence the 'read' method of the snipclass omitted for fast proto
(define black-style-delta (make-object style-delta% 'change-normal-color)) (define black-style-delta (make-object style-delta% 'change-normal-color))
(define green-style-delta (make-object style-delta%)) (define green-style-delta (make-object style-delta%))
(send green-style-delta set-delta-foreground "forest green") (void (send green-style-delta set-delta-foreground "forest green"))
(define turn-snip% (define turn-snip%
(class snip% (class snip%

View File

@ -1,6 +1,6 @@
#lang scheme #lang racket/base
(require mred/mred) (require racket/gui/base racket/class)
(provide bitmap-message%) (provide bitmap-message%)
(define bitmap-message% (define bitmap-message%

View File

@ -1,4 +1,4 @@
#lang scheme/base #lang racket/base
#| #|
@ -10,11 +10,11 @@ profile todo:
(require errortrace/errortrace-key (require errortrace/errortrace-key
scheme/unit scheme/unit
scheme/contract racket/contract
errortrace/stacktrace errortrace/stacktrace
scheme/class racket/class
scheme/path racket/path
scheme/gui/base racket/gui/base
string-constants string-constants
framework framework
framework/private/bday framework/private/bday
@ -23,9 +23,9 @@ profile todo:
"bindings-browser.ss" "bindings-browser.ss"
net/sendurl net/sendurl
net/url net/url
scheme/match racket/match
mrlib/include-bitmap mrlib/include-bitmap
(for-syntax scheme/base)) (for-syntax racket/base))
(define orig (current-output-port)) (define orig (current-output-port))

View File

@ -1,12 +1,12 @@
#lang scheme/base #lang racket/base
(require mred (require mred
scheme/class racket/class
scheme/cmdline racket/cmdline
scheme/list racket/list
framework/private/bday framework/private/bday
framework/splash framework/splash
scheme/file racket/file
"eb.ss") "eb.ss")
(define files-to-open (command-line #:args filenames filenames)) (define files-to-open (command-line #:args filenames filenames))

View File

@ -1,4 +1,4 @@
#lang scheme/base #lang racket/base
(require scheme/unit) (require scheme/unit)
(provide drscheme:eval^ (provide drscheme:eval^

View File

@ -1,7 +1,7 @@
#lang scheme/base #lang racket/base
(require scheme/class (require racket/class
framework/splash framework/splash
scheme/gui/base) racket/gui/base)
(provide install-eb) (provide install-eb)
(define (install-eb) (define (install-eb)

View File

@ -1,6 +1,6 @@
#lang scheme/base #lang racket/base
(require scheme/class (require racket/class
scheme/gui/base) racket/gui/base)
(provide get-enclosing-editor-frame) (provide get-enclosing-editor-frame)

View File

@ -1,9 +1,9 @@
#lang mzscheme #lang racket/base
(require mred (require mred
mzlib/unit scheme/unit
mzlib/port racket/port
mzlib/class racket/class
syntax/toplevel syntax/toplevel
framework framework
"drsig.ss") "drsig.ss")
@ -11,7 +11,7 @@
;; to ensure this guy is loaded (and the snipclass installed) in the drscheme namespace & eventspace ;; to ensure this guy is loaded (and the snipclass installed) in the drscheme namespace & eventspace
;; these things are for effect only! ;; these things are for effect only!
(require mrlib/cache-image-snip (require mrlib/cache-image-snip
(prefix image-core: mrlib/image-core)) (prefix-in image-core: mrlib/image-core))
(define op (current-output-port)) (define op (current-output-port))
(define (oprintf . args) (apply fprintf op args)) (define (oprintf . args) (apply fprintf op args))
@ -173,7 +173,7 @@
(error-print-width 250) (error-print-width 250)
(current-ps-setup (make-object ps-setup%)) (current-ps-setup (make-object ps-setup%))
(current-namespace (make-namespace 'empty)) (current-namespace (make-empty-namespace))
(for-each (λ (x) (namespace-attach-module drscheme:init:system-namespace x)) (for-each (λ (x) (namespace-attach-module drscheme:init:system-namespace x))
to-be-copied-module-names)) to-be-copied-module-names))

View File

@ -1,8 +1,8 @@
#lang mzscheme #lang racket/base
(require mzlib/unit (require scheme/unit
mzlib/class racket/class
racket/gui/base
"drsig.ss" "drsig.ss"
mred
framework framework
string-constants) string-constants)

View File

@ -1,9 +1,8 @@
#lang scheme/unit #lang scheme/unit
(require string-constants (require string-constants
mzlib/match racket/match
mzlib/class racket/class
mzlib/string racket/string
mzlib/list
"drsig.ss" "drsig.ss"
mred mred
framework framework
@ -11,7 +10,7 @@
net/head net/head
setup/plt-installer setup/plt-installer
help/bug-report help/bug-report
scheme/file) racket/file)
(import [prefix drscheme:unit: drscheme:unit^] (import [prefix drscheme:unit: drscheme:unit^]
[prefix drscheme:app: drscheme:app^] [prefix drscheme:app: drscheme:app^]

View File

@ -1,6 +1,6 @@
#lang scheme/unit #lang scheme/unit
(require scheme/class (require racket/class
"drsig.ss") "drsig.ss")
(import [prefix drscheme:unit: drscheme:unit^] (import [prefix drscheme:unit: drscheme:unit^]

View File

@ -1,9 +1,9 @@
#lang scheme/unit #lang scheme/unit
(require scheme/gui/base (require racket/gui/base
browser/external browser/external
framework framework
scheme/class racket/class
net/url net/url
setup/dirs setup/dirs
help/search help/search

View File

@ -1,8 +1,8 @@
#lang scheme/base #lang racket/base
(provide draw-honu) (provide draw-honu)
(require scheme/class (require racket/class
scheme/gui/base racket/gui/base
"palaka.ss") "palaka.ss")
(define pi (atan 0 -1)) (define pi (atan 0 -1))

View File

@ -1,8 +1,7 @@
#lang scheme/unit #lang scheme/unit
(require string-constants (require string-constants
"drsig.ss" "drsig.ss"
mzlib/list racket/gui/base)
mred)
(import) (import)

View File

@ -2,7 +2,7 @@
(require typed/mred/mred (require typed/mred/mred
typed/framework/framework typed/framework/framework
scheme/class racket/class
string-constants/string-constant) string-constants/string-constant)

View File

@ -1,4 +1,4 @@
#lang mzscheme #lang racket/base
(provide break-threads) (provide break-threads)
(define super-cust (current-custodian)) (define super-cust (current-custodian))
(define first-child (make-custodian)) (define first-child (make-custodian))

View File

@ -1,28 +1,28 @@
#lang mzscheme #lang racket/base
(require mred (require racket/gui/base
mzlib/class) racket/class)
(provide (all-from-except mred frame%) (provide (except-out (all-from-out racket/gui/base) frame%)
(rename registering-frame% frame%) (rename-out [registering-frame% frame%])
lookup-frame-name) lookup-frame-name)
(define (lookup-frame-name frame) (define (lookup-frame-name frame)
(semaphore-wait label-sema) (semaphore-wait label-sema)
(begin0 (begin0
(hash-table-get label-ht frame (λ () #f)) (hash-ref label-ht frame (λ () #f))
(semaphore-post label-sema))) (semaphore-post label-sema)))
(define label-sema (make-semaphore 1)) (define label-sema (make-semaphore 1))
(define label-ht (make-hash-table 'weak)) (define label-ht (make-weak-hasheq))
(define registering-frame% (define registering-frame%
(class frame% (class frame%
(define/override (set-label x) (define/override (set-label x)
(semaphore-wait label-sema) (semaphore-wait label-sema)
(hash-table-put! label-ht this x) (hash-set! label-ht this x)
(semaphore-post label-sema) (semaphore-post label-sema)
(super set-label x)) (super set-label x))
(inherit get-label) (inherit get-label)
(super-instantiate ()) (super-instantiate ())
(semaphore-wait label-sema) (semaphore-wait label-sema)
(hash-table-put! label-ht this (get-label)) (hash-set! label-ht this (get-label))
(semaphore-post label-sema))) (semaphore-post label-sema)))

View File

@ -1,13 +1,13 @@
#lang scheme/base #lang racket/base
(require scheme/unit (require scheme/unit
mrlib/hierlist mrlib/hierlist
scheme/class racket/class
scheme/contract racket/contract
scheme/string racket/string
scheme/list racket/list
racket/gui/base
"drsig.ss" "drsig.ss"
string-constants string-constants
mred
framework framework
setup/getinfo setup/getinfo
syntax/toplevel syntax/toplevel
@ -1252,7 +1252,12 @@
(message-box (message-box
(string-constant drscheme) (string-constant drscheme)
(format (format
"The drscheme-language-position, drscheme-language-modules, drscheme-language-numbers, and drscheme-language-readers specifications aren't correct. Expected (listof (cons string (listof string))), (listof (listof string)), (listof (listof number)), (listof string), (listof string), and (listof module-spec) respectively, where the lengths of the outer lists are the same. Got ~e, ~e, ~e, ~e, ~e, and ~e" (string-append
"The drscheme-language-position, drscheme-language-modules, drscheme-language-numbers,"
" and drscheme-language-readers specifications aren't correct. Expected"
" (listof (cons string (listof string))), (listof (listof string)), (listof (listof number)), (listof string),"
" (listof string), and (listof module-spec) respectively, where the lengths of the outer lists are the same."
" Got ~e, ~e, ~e, ~e, ~e, and ~e")
lang-positions lang-positions
lang-modules lang-modules
numberss numberss
@ -1431,7 +1436,7 @@
(let ([words #f]) (let ([words #f])
(λ () (λ ()
(unless words (unless words
(set! words (text:get-completions/manuals '(scheme/base scheme/contract)))) (set! words (text:get-completions/manuals '(racket/base racket/contract))))
words))) words)))
(define get-all-manual-keywords (define get-all-manual-keywords

View File

@ -1,14 +1,14 @@
#reader scribble/reader #reader scribble/reader
#lang scheme/base #lang racket/base
(require (for-syntax scheme/base) (require (for-syntax racket/base)
scribble/srcdoc scribble/srcdoc
scheme/class racket/class
scheme/gui/base racket/gui/base
scheme/contract racket/contract
"recon.ss") "recon.ss")
(require/doc scheme/base scribble/manual) (require/doc racket/base scribble/manual)
(require (for-meta 2 scheme/base)) (require (for-meta 2 racket/base))
(provide language-object-abstraction) (provide language-object-abstraction)

View File

@ -9,17 +9,17 @@
;; NOTE: this module instantiates stacktrace itself, so we have ;; NOTE: this module instantiates stacktrace itself, so we have
;; to be careful to not mix that instantiation with the one ;; to be careful to not mix that instantiation with the one
;; drscheme/private/debug.ss does. errortrace-lib's is for the ;; drracket/private/debug.ss does. errortrace-lib's is for the
;; compilation handling, DrScheme's is for profiling and test coverage ;; compilation handling, DrScheme's is for profiling and test coverage
;; (which do not do compilation) ;; (which do not do compilation)
(prefix-in el: errortrace/errortrace-lib) (prefix-in el: errortrace/errortrace-lib)
mzlib/pconvert mzlib/pconvert
scheme/pretty racket/pretty
mzlib/struct mzlib/struct
scheme/class racket/class
scheme/file racket/file
scheme/list racket/list
compiler/embed compiler/embed
launcher launcher
mred mred

View File

@ -1,8 +1,8 @@
#lang scheme/base #lang racket/base
(provide startup) (provide startup)
(require scheme/file) (require racket/file)
(define (read-from-string s) (read (open-input-string s))) (define (read-from-string s) (read (open-input-string s)))

View File

@ -1,9 +1,9 @@
#lang scheme/base #lang racket/base
(require scheme/gui/base "launcher-bootstrap.ss") (require racket/gui/base "launcher-bootstrap.ss")
(current-namespace (make-gui-empty-namespace)) (current-namespace (make-gui-empty-namespace))
(namespace-require 'scheme/gui/base) (namespace-require 'racket/gui/base)
(namespace-require 'scheme/class) (namespace-require 'racket/class)
(startup) (startup)

View File

@ -1,8 +1,8 @@
#lang scheme/base #lang racket/base
(require "launcher-bootstrap.ss") (require "launcher-bootstrap.ss")
(current-namespace (make-base-empty-namespace)) (current-namespace (make-base-empty-namespace))
(namespace-require 'scheme/base) (namespace-require 'racket/base)
(startup) (startup)

View File

@ -1,4 +1,4 @@
#lang scheme/base #lang racket/base
(require scheme/unit (require scheme/unit
"modes.ss" "modes.ss"
"font.ss" "font.ss"

View File

@ -7,7 +7,7 @@
framework framework
mzlib/class mzlib/class
mzlib/list mzlib/list
scheme/path racket/path
browser/external browser/external
setup/plt-installer) setup/plt-installer)

View File

@ -1,7 +1,7 @@
#lang scheme/unit #lang scheme/unit
(require string-constants (require string-constants
mzlib/class racket/class
mzlib/list racket/list
framework framework
"drsig.ss") "drsig.ss")
@ -23,7 +23,7 @@
(define (not-a-language-language? l) (define (not-a-language-language? l)
(and (not (null? l)) (and (not (null? l))
(equal? (car (last-pair l)) (equal? (last l)
(string-constant no-language-chosen)))) (string-constant no-language-chosen))))
(define (add-initial-modes) (define (add-initial-modes)

View File

@ -1,7 +1,7 @@
#lang scheme/base #lang racket/base
(require mred (require mred
scheme/class racket/class
syntax/moddep syntax/moddep
syntax/toplevel syntax/toplevel
framework/framework framework/framework
@ -9,7 +9,7 @@
mrlib/graph mrlib/graph
"drsig.ss" "drsig.ss"
scheme/unit scheme/unit
scheme/async-channel racket/async-channel
setup/private/lib-roots) setup/private/lib-roots)
(define-struct req (filename key)) (define-struct req (filename key))

View File

@ -1,12 +1,12 @@
#lang scheme/base #lang racket/base
(provide module-language-tools@) (provide module-language-tools@)
(require mrlib/switchable-button (require mrlib/switchable-button
mrlib/bitmap-label mrlib/bitmap-label
scheme/contract racket/contract
framework framework
scheme/unit scheme/unit
scheme/class racket/class
scheme/gui/base racket/gui/base
"drsig.ss") "drsig.ss")
(define op (current-output-port)) (define op (current-output-port))

View File

@ -1,11 +1,11 @@
#lang scheme/base #lang racket/base
(provide module-language@) (provide module-language@)
(require scheme/unit (require scheme/unit
scheme/class racket/class
scheme/list racket/list
scheme/path racket/path
scheme/contract racket/contract
mred mred
compiler/embed compiler/embed
compiler/cm compiler/cm
@ -382,7 +382,7 @@
#:literal-expression #:literal-expression
(begin (begin
(parameterize ([current-namespace (make-base-empty-namespace)]) (parameterize ([current-namespace (make-base-empty-namespace)])
(namespace-require 'scheme/base) (namespace-require 'racket/base)
(compile (compile
`(namespace-require '',(string->symbol (path->string short-program-name)))))) `(namespace-require '',(string->symbol (path->string short-program-name))))))
#:cmdline '("-U" "--"))))) #:cmdline '("-U" "--")))))
@ -672,7 +672,7 @@
(raise-hopeless-syntax-error "bad syntax in name position of module" (raise-hopeless-syntax-error "bad syntax in name position of module"
stx name)) stx name))
(when filename (check-filename-matches filename name* stx)) (when filename (check-filename-matches filename name* stx))
(let* (;; rewrite the module to use the scheme/base version of `module' (let* (;; rewrite the module to use the racket/base version of `module'
[mod (datum->syntax #'here 'module mod)] [mod (datum->syntax #'here 'module mod)]
[expr (datum->syntax stx `(,mod ,name ,lang . ,body) stx stx)]) [expr (datum->syntax stx `(,mod ,name ,lang . ,body) stx stx)])
(values name lang expr))) (values name lang expr)))

View File

@ -2,8 +2,8 @@
(require framework (require framework
mzlib/class mzlib/class
mred mred
scheme/file racket/file
scheme/path racket/path
mzlib/thread mzlib/thread
mzlib/async-channel mzlib/async-channel
string-constants string-constants

View File

@ -1,6 +1,6 @@
#lang mzscheme #lang racket/base
(require mred (require mred
mzlib/class racket/class
framework) framework)
(provide snip-class) (provide snip-class)

View File

@ -1,5 +1,5 @@
#lang scheme/base #lang racket/base
(require scheme/class scheme/gui/base) (require racket/class racket/gui/base)
(provide draw-palaka palaka-pattern-size) (provide draw-palaka palaka-pattern-size)
(define scale 1) (define scale 1)

View File

@ -1,6 +1,6 @@
#lang scheme/base #lang racket/base
(require (for-syntax scheme/base) (require (for-syntax racket/base)
framework/framework) framework/framework)
(provide (rename-out [-preferences:get preferences:get]) (provide (rename-out [-preferences:get preferences:get])

View File

@ -1,6 +1,6 @@
#lang scheme/base #lang racket/base
(require scheme/gui/base (require racket/gui/base
scheme/class racket/class
profile/sampler profile/sampler
profile/render-text profile/render-text
profile/analyzer profile/analyzer

View File

@ -1,5 +1,5 @@
#lang scheme/base #lang racket/base
(require (for-syntax scheme/base)) (require (for-syntax racket/base))
(provide reconstitute) (provide reconstitute)
(begin-for-syntax (begin-for-syntax

View File

@ -1,4 +1,4 @@
#lang scheme/base #lang racket/base
#| #|
@ -20,15 +20,15 @@ TODO
;; user's io ports, to aid any debugging printouts. ;; user's io ports, to aid any debugging printouts.
;; (esp. useful when debugging the users's io) ;; (esp. useful when debugging the users's io)
(require scheme/class (require racket/class
scheme/path racket/path
scheme/pretty racket/pretty
scheme/unit scheme/unit
scheme/list racket/list
string-constants string-constants
setup/xref setup/xref
scheme/gui/base racket/gui/base
framework framework
browser/external browser/external
"drsig.ss" "drsig.ss"

View File

@ -1,7 +1,7 @@
#lang mzscheme #lang racket/base
(require mzlib/class (require racket/class
mzlib/pretty racket/pretty
mred) racket/gui/base)
(define head-size 40) (define head-size 40)
(define small-bitmap-factor 1/2) (define small-bitmap-factor 1/2)

View File

@ -1,9 +1,9 @@
#lang scheme/unit #lang scheme/unit
(require scheme/class (require racket/class
scheme/list racket/list
scheme/runtime-path racket/runtime-path
scheme/contract racket/contract
setup/getinfo setup/getinfo
mred mred
framework framework
@ -13,7 +13,7 @@
mrlib/switchable-button mrlib/switchable-button
string-constants) string-constants)
(require (for-syntax scheme/base scheme/match)) (require (for-syntax racket/base racket/match))
(import [prefix drscheme:frame: drscheme:frame^] (import [prefix drscheme:frame: drscheme:frame^]
[prefix drscheme:unit: drscheme:unit^] [prefix drscheme:unit: drscheme:unit^]

View File

@ -1,12 +1,12 @@
#lang scheme/base #lang racket/base
(require scheme/contract (require racket/contract
scheme/unit scheme/unit
scheme/class racket/class
scheme/path racket/path
scheme/port racket/port
scheme/list racket/list
scheme/gui/base racket/gui/base
string-constants string-constants
framework framework
(prefix-in tr: trace/stacktrace) (prefix-in tr: trace/stacktrace)

View File

@ -1,5 +1,4 @@
#reader scribble/reader #lang at-exp racket/base
#lang scheme/base
(require scribble/decode (require scribble/decode
scribble/manual) scribble/manual)

View File

@ -1,4 +1,4 @@
#lang scheme/base #lang racket/base
#| #|
closing: closing:
@ -11,12 +11,12 @@ module browser threading seems wrong.
|# |#
(require scheme/contract (require racket/contract
scheme/unit scheme/unit
scheme/class racket/class
scheme/path racket/path
scheme/port racket/port
scheme/list racket/list
string-constants string-constants
framework framework
mrlib/name-message mrlib/name-message

View File

@ -1,4 +1,4 @@
#lang scheme/base #lang racket/base
(require scheme/gui/base (require scheme/gui/base
framework framework
scheme/class) scheme/class)

View File

@ -1,4 +1,4 @@
#lang scheme/base #lang racket/base
(require scheme/class (require scheme/class
scheme/gui/base scheme/gui/base
string-constants/string-constant) string-constants/string-constant)

View File

@ -1,4 +1,4 @@
#lang scheme/base #lang racket/base
#| #|
Check Syntax separates two classes of identifiers, Check Syntax separates two classes of identifiers,
@ -2276,16 +2276,28 @@ If the namespace does not, they are colored the unbound color.
(parameterize ([current-namespace user-namespace] (parameterize ([current-namespace user-namespace]
[current-directory user-directory] [current-directory user-directory]
[current-load-relative-directory user-directory]) [current-load-relative-directory user-directory])
(let ([ans (with-handlers ([exn:fail? (λ (x) #f)]) (let* ([rkt-path/mod-path
(with-handlers ([exn:fail? (λ (x) #f)])
(cond (cond
[(module-path-index? datum) [(module-path-index? datum)
(resolved-module-path-name (resolved-module-path-name
(module-path-index-resolve datum))] (module-path-index-resolve datum))]
[else [else
(resolved-module-path-name (resolved-module-path-name
((current-module-name-resolver) datum #f #f))]))]) ((current-module-name-resolver) datum #f #f))]))]
(and (path? ans) [rkt-path/f (and (path? rkt-path/mod-path) rkt-path/mod-path)])
ans)))) (let/ec k
(unless (path? rkt-path/f) (k rkt-path/f))
(when (file-exists? rkt-path/f) (k rkt-path/f))
(let* ([bts (path->bytes rkt-path/f)]
[len (bytes-length bts)])
(unless (and (len . >= . 4)
(bytes=? #".rkt" (subbytes bts (- len 4))))
(k rkt-path/f))
(let ([ss-path (bytes->path (bytes-append (subbytes bts 0 (- len 4)) #".ss"))])
(unless (file-exists? ss-path)
(k rkt-path/f))
ss-path))))))
;; make-require-open-menu : path -> menu -> void ;; make-require-open-menu : path -> menu -> void
(define (make-require-open-menu file) (define (make-require-open-menu file)

View File

@ -1,4 +1,4 @@
#lang at-exp scheme/base #lang at-exp racket/base
#| #|

View File

@ -1,4 +1,5 @@
(module tool mzscheme #lang racket/base
(require "private/drsig.ss") (require "private/drsig.ss")
(provide drscheme:tool^ (provide drscheme:tool^
drscheme:tool-exports^)) drscheme:tool-exports^)

3
collects/meta/props Executable file → Normal file
View File

@ -812,6 +812,7 @@ path/s is either such a string or a list of them.
"collects/handin-server/web-status-server.ss" drdr:command-line "mzc ~s" "collects/handin-server/web-status-server.ss" drdr:command-line "mzc ~s"
"collects/help" responsible (robby) "collects/help" responsible (robby)
"collects/help/bug-report.ss" drdr:command-line "mred-text -t ~s" "collects/help/bug-report.ss" drdr:command-line "mred-text -t ~s"
"collects/help/help.ss" drdr:command-line "mzc ~s"
"collects/hierlist/hierlist.ss" drdr:command-line "mred-text -t ~s" "collects/hierlist/hierlist.ss" drdr:command-line "mred-text -t ~s"
"collects/honu" responsible (mflatt rafkind) "collects/honu" responsible (mflatt rafkind)
"collects/htdp" responsible (matthias) "collects/htdp" responsible (matthias)
@ -897,8 +898,8 @@ path/s is either such a string or a list of them.
"collects/make" responsible (mflatt) "collects/make" responsible (mflatt)
"collects/meta" responsible (eli) "collects/meta" responsible (eli)
"collects/meta/check-dists.ss" drdr:command-line "" "collects/meta/check-dists.ss" drdr:command-line ""
"collects/meta/drdr" responsible (jay) drdr:command-line ""
"collects/meta/contrib/completion/racket-completion.bash" responsible (samth sstrickl) drdr:command-line "" "collects/meta/contrib/completion/racket-completion.bash" responsible (samth sstrickl) drdr:command-line ""
"collects/meta/drdr" responsible (jay) drdr:command-line ""
"collects/mred/edit-main.ss" drdr:command-line "mzc ~s" "collects/mred/edit-main.ss" drdr:command-line "mzc ~s"
"collects/mred/edit.ss" drdr:command-line "mred-text -t ~s" "collects/mred/edit.ss" drdr:command-line "mred-text -t ~s"
"collects/mred/lang/main.ss" drdr:command-line "mred-text -t ~s" "collects/mred/lang/main.ss" drdr:command-line "mred-text -t ~s"

View File

@ -1,6 +0,0 @@
#lang racket
(require racket/init
scheme/gui/base)
(provide (all-from-out racket/init
scheme/gui/base))

View File

@ -22,6 +22,7 @@
for/last for*/last for/last for*/last
for/hash for*/hash for/hash for*/hash
for/hasheq for*/hasheq for/hasheq for*/hasheq
for/hasheqv for*/hasheqv
for/fold/derived for*/fold/derived for/fold/derived for*/fold/derived
@ -952,6 +953,14 @@
#`(let-values ([(key val) #,x]) #`(let-values ([(key val) #,x])
(hash-set table key val)))) (hash-set table key val))))
(define-for-variants (for/hasheqv for*/hasheqv)
([table #hasheqv()])
(lambda (x) x)
(lambda (rhs) rhs)
(lambda (x)
#`(let-values ([(key val) #,x])
(hash-set table key val))))
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; specific sequences ;; specific sequences

View File

@ -7,7 +7,9 @@
set-member? set-add set-remove set-member? set-add set-remove
set-union set-intersect set-subtract set-union set-intersect set-subtract
set-map set-for-each set-map set-for-each
(rename-out [*in-set in-set])) (rename-out [*in-set in-set])
for/set for/seteq for/seteqv
for*/set for*/seteq for*/seteqv)
(define-struct set (ht) (define-struct set (ht)
#:omit-define-syntaxes #:omit-define-syntaxes
@ -206,3 +208,17 @@
#t #t
;; loop args ;; loop args
((hash-iterate-next ht pos)))]]))) ((hash-iterate-next ht pos)))]])))
(define-syntax-rule (define-for for/fold/derived for/set set)
(define-syntax (for/set stx)
(syntax-case stx ()
[(_ bindings . body)
(quasisyntax/loc stx
(for/fold/derived #,stx ([s (set)]) bindings (set-add s (let () . body))))])))
(define-for for/fold/derived for/set set)
(define-for for*/fold/derived for*/set set)
(define-for for/fold/derived for/seteq seteq)
(define-for for*/fold/derived for*/seteq seteq)
(define-for for/fold/derived for/seteqv seteqv)
(define-for for*/fold/derived for*/seteqv seteqv)

View File

@ -1,3 +1,5 @@
#lang scheme/private #lang scheme/private
(provide (except-out (all-from-out racket/base) struct)) (provide (except-out (all-from-out racket/base)
struct
hash hasheq hasheqv))

1050
collects/scribble/racket.ss Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,985 +1,3 @@
(module scheme scheme/base #lang racket/base
(require "core.ss" (require "racket.ss")
"basic.ss" (provide (all-from-out "racket.ss"))
"search.ss"
"private/manual-sprop.ss"
"private/on-demand.ss"
mzlib/class
mzlib/for
syntax/modresolve
syntax/modcode
(for-syntax scheme/base))
(provide define-code
to-element
to-element/no-color
to-paragraph
to-paragraph/prefix
syntax-ize
syntax-ize-hook
current-keyword-list
current-variable-list
current-meta-list
input-color
output-color
input-background-color
no-color
reader-color
result-color
keyword-color
comment-color
paren-color
meta-color
value-color
symbol-color
variable-color
opt-color
error-color
syntax-link-color
value-link-color
module-color
module-link-color
block-color
highlighted-color
(struct-out var-id)
(struct-out shaped-parens)
(struct-out just-context)
(struct-out alternate-display)
(struct-out literal-syntax)
(for-syntax make-variable-id
variable-id?
make-element-id-transformer
element-id-transformer?))
(define (make-scheme-style s #:tt? [tt? #t])
(make-style s (if tt?
(cons 'tt-chars scheme-properties)
scheme-properties)))
(define-on-demand output-color (make-scheme-style "ScmOut"))
(define-on-demand input-color (make-scheme-style "ScmIn"))
(define-on-demand input-background-color (make-scheme-style "ScmInBG"))
(define-on-demand no-color (make-scheme-style "ScmPlain"))
(define-on-demand reader-color (make-scheme-style "ScmRdr"))
(define-on-demand result-color (make-scheme-style "ScmRes"))
(define-on-demand keyword-color (make-scheme-style "ScmKw"))
(define-on-demand comment-color (make-scheme-style "ScmCmt"))
(define-on-demand paren-color (make-scheme-style "ScmPn"))
(define-on-demand meta-color (make-scheme-style "ScmMeta"))
(define-on-demand value-color (make-scheme-style "ScmVal"))
(define-on-demand symbol-color (make-scheme-style "ScmSym"))
(define-on-demand variable-color (make-scheme-style "ScmVar"))
(define-on-demand opt-color (make-scheme-style "ScmOpt"))
(define-on-demand error-color (make-scheme-style "ScmErr" #:tt? #f))
(define-on-demand syntax-link-color (make-scheme-style "ScmStxLink"))
(define-on-demand value-link-color (make-scheme-style "ScmValLink"))
(define-on-demand module-color (make-scheme-style "ScmMod"))
(define-on-demand module-link-color (make-scheme-style "ScmModLink"))
(define-on-demand block-color (make-scheme-style "ScmBlk"))
(define-on-demand highlighted-color (make-scheme-style "highlighted" #:tt? #f))
(define current-keyword-list
(make-parameter null))
(define current-variable-list
(make-parameter null))
(define current-meta-list
(make-parameter null))
(define defined-names (make-hasheq))
(define-struct (sized-element element) (length))
(define-struct (spaces element) (cnt))
(define (literalize-spaces i)
(let ([m (regexp-match-positions #rx" +" i)])
(if m
(let ([cnt (- (cdar m) (caar m))])
(make-spaces #f
(list
(literalize-spaces (substring i 0 (caar m)))
(hspace cnt)
(literalize-spaces (substring i (cdar m))))
cnt))
i)))
(define line-breakable-space (make-element 'tt " "))
;; These caches intentionally record a key with the value.
;; That way, when the value is no longer used, the key
;; goes away, and the entry is gone.
(define id-element-cache (make-weak-hash))
(define element-cache (make-weak-hash))
(define-struct (cached-delayed-element delayed-element) (cache-key))
(define-struct (cached-element element) (cache-key))
(define (make-id-element c s)
(let* ([key (and id-element-cache
(let ([b (identifier-label-binding c)])
(vector (syntax-e c)
(module-path-index->taglet (caddr b))
(cadddr b)
(list-ref b 5))))])
(or (and key
(let ([b (hash-ref id-element-cache key #f)])
(and b
(weak-box-value b))))
(let ([e (make-cached-delayed-element
(lambda (renderer sec ri)
(let* ([tag (find-scheme-tag sec ri c #f)])
(if tag
(list
(case (car tag)
[(form)
(make-link-element syntax-link-color (list s) tag)]
[else
(make-link-element value-link-color (list s) tag)]))
(list
(make-element "badlink"
(make-element value-link-color s))))))
(lambda () s)
(lambda () s)
key)])
(when key
(hash-set! id-element-cache key (make-weak-box e)))
e))))
(define (make-element/cache style content)
(if (and element-cache
(string? content))
(let ([key (vector style content)])
(let ([b (hash-ref element-cache key #f)])
(or (and b (weak-box-value b))
(let ([e (make-cached-element style content key)])
(hash-set! element-cache key (make-weak-box e))
e))))
(make-element style content)))
(define (to-quoted qs qq? quote-depth out color? inc!)
(if (and qq? (zero? quote-depth))
(begin
(out qs (and color? value-color))
(inc!)
(add1 quote-depth))
quote-depth))
(define (to-unquoted qq? quote-depth out color? inc!)
(if (or (not qq?) (zero? quote-depth))
quote-depth
(begin
(out "," (and color? meta-color))
(inc!)
(to-unquoted qq? (sub1 quote-depth) out color? inc!))))
(define (typeset-atom c out color? quote-depth qq?)
(if (and (var-id? (syntax-e c))
(zero? quote-depth))
(out (format "~s" (let ([v (var-id-sym (syntax-e c))])
(if (syntax? v)
(syntax-e v)
v)))
variable-color)
(let*-values ([(is-var?) (and (identifier? c)
(memq (syntax-e c) (current-variable-list)))]
[(s it? sub?)
(let ([sc (syntax-e c)])
(let ([s (or (syntax-property c 'display-string)
(format "~s" (if (literal-syntax? sc)
(literal-syntax-stx sc)
(if (var-id? sc)
(var-id-sym sc)
sc))))])
(if (and (symbol? sc)
((string-length s) . > . 1)
(char=? (string-ref s 0) #\_)
(not (or (identifier-label-binding c)
is-var?)))
(values (substring s 1) #t #f)
(values s #f #f))))])
(let ([quote-depth (if (and qq? (identifier? c))
(let ([quote-depth
(if (and (quote-depth . < . 2)
(memq (syntax-e c) '(unquote unquote-splicing)))
(to-unquoted qq? quote-depth out color? void)
quote-depth)])
(to-quoted "'" qq? quote-depth out color? void))
quote-depth)])
(if (or (element? (syntax-e c))
(delayed-element? (syntax-e c))
(part-relative-element? (syntax-e c)))
(out (syntax-e c) #f)
(out (if (and (identifier? c)
color?
(quote-depth . <= . 0)
(not (or it? is-var?)))
(if (pair? (identifier-label-binding c))
(make-id-element c s)
s)
(literalize-spaces s))
(cond
[(positive? quote-depth) value-color]
[(let ([v (syntax-e c)])
(or (number? v)
(string? v)
(bytes? v)
(char? v)
(regexp? v)
(byte-regexp? v)
(boolean? v)))
value-color]
[(identifier? c)
(cond
[is-var?
variable-color]
[(and (identifier? c)
(memq (syntax-e c) (current-keyword-list)))
keyword-color]
[(and (identifier? c)
(memq (syntax-e c) (current-meta-list)))
meta-color]
[it? variable-color]
[else symbol-color])]
[else paren-color])
(string-length s)))))))
(define omitable (make-style #f '(omitable)))
(define (gen-typeset c multi-line? prefix1 prefix suffix color? qq?)
(let* ([c (syntax-ize c 0 #:qq? qq?)]
[content null]
[docs null]
[first (syntax-case c (code:line)
[(code:line e . rest) #'e]
[else c])]
[init-col (or (syntax-column first) 0)]
[src-col init-col]
[inc-src-col (lambda () (set! src-col (add1 src-col)))]
[dest-col 0]
[highlight? #f]
[col-map (make-hash)]
[next-col-map (make-hash)]
[line (or (syntax-line first) 0)])
(define (finish-line!)
(when multi-line?
(set! docs (cons (make-paragraph omitable (reverse content))
docs))
(set! content null)))
(define out
(case-lambda
[(v cls)
(out v cls (let sz-loop ([v v])
(cond
[(string? v) (string-length v)]
[(list? v) (for/fold ([s 0]) ([v (in-list v)]) (+ s (sz-loop v)))]
[(sized-element? v) (sized-element-length v)]
[(element? v)
(sz-loop (element-content v))]
[(delayed-element? v)
(content-width v)]
[(part-relative-element? v)
(content-width v)]
[(spaces? v)
(+ (sz-loop (car (element-content v)))
(spaces-cnt v)
(sz-loop (caddr (element-content v))))]
[else 1])))]
[(v cls len)
(unless (equal? v "")
(cond
[(spaces? v)
(out (car (element-content v)) cls 0)
(out (cadr (element-content v)) #f 0)
(out (caddr (element-content v)) cls len)]
[(equal? v "\n")
(if multi-line?
(begin
(finish-line!)
(out prefix cls))
(out " " cls))]
[else
(set! content (cons ((if highlight?
(lambda (c)
(make-element highlighted-color c))
values)
(if (and color? cls)
(make-element/cache cls v)
v))
content))
(set! dest-col (+ dest-col len))]))]))
(define advance
(case-lambda
[(c init-line! delta)
(let ([c (+ delta (or (syntax-column c) 0))]
[l (syntax-line c)])
(let ([new-line? (and l (l . > . line))])
(when new-line?
(for ([i (in-range (- l line))])
(out "\n" no-color))
(set! line l)
(set! col-map next-col-map)
(set! next-col-map (make-hash))
(init-line!))
(let ([d-col (let ([def-val (+ dest-col (- c src-col))])
(if new-line?
(hash-ref col-map c def-val)
def-val))])
(let ([amt (- d-col dest-col)])
(when (positive? amt)
(let ([old-dest-col dest-col])
(out (if (and (= 1 amt) (not multi-line?))
line-breakable-space ; allows a line break to replace the space
(hspace amt))
#f)
(set! dest-col (+ old-dest-col amt))))))
(set! src-col c)
(hash-set! next-col-map src-col dest-col)))]
[(c init-line!) (advance c init-line! 0)]))
(define (convert-infix c quote-depth qq?)
(let ([l (syntax->list c)])
(and l
((length l) . >= . 3)
((or (syntax-position (car l)) -inf.0)
. > .
(or (syntax-position (cadr l)) +inf.0))
(let ([a (car l)])
(let loop ([l (cdr l)]
[prev null])
(cond
[(null? l) #f] ; couldn't unwind
[else (let ([p2 (syntax-position (car l))])
(if (and p2
(p2 . > . (syntax-position a)))
(datum->syntax c
(append
(reverse prev)
(list
(datum->syntax
a
(let ([val? (positive? quote-depth)])
(make-sized-element
(if val? value-color #f)
(list
(make-element/cache (if val? value-color paren-color) '". ")
(typeset a #f "" "" "" (not val?) qq?)
(make-element/cache (if val? value-color paren-color) '" ."))
(+ (syntax-span a) 4)))
(list (syntax-source a)
(syntax-line a)
(- (syntax-column a) 2)
(- (syntax-position a) 2)
(+ (syntax-span a) 4))
a))
l)
c
c)
(loop (cdr l)
(cons (car l) prev))))]))))))
(define (no-fancy-chars s)
(cond
[(eq? s 'rsquo) "'"]
[else s]))
(define (loop init-line! quote-depth qq?)
(lambda (c)
(cond
[(eq? 'code:blank (syntax-e c))
(advance c init-line!)]
[(and (pair? (syntax-e c))
(eq? (syntax-e (car (syntax-e c))) 'code:comment))
(let ([l (syntax->list c)])
(unless (and l (= 2 (length l)))
(raise-syntax-error
#f
"does not have a single sub-form"
c)))
(advance c init-line!)
(out ";" comment-color)
(out 'nbsp comment-color)
(let ([v (syntax->datum (cadr (syntax->list c)))])
(if (paragraph? v)
(map (lambda (v)
(let ([v (no-fancy-chars v)])
(if (or (string? v) (symbol? v))
(out v comment-color)
(out v #f))))
(paragraph-content v))
(out (no-fancy-chars v) comment-color)))]
[(and (pair? (syntax-e c))
(eq? (syntax-e (car (syntax-e c))) 'code:contract))
(advance c init-line!)
(out "; " comment-color)
(let* ([l (cdr (syntax->list c))]
[s-col (or (syntax-column (car l)) src-col)])
(set! src-col s-col)
(for-each (loop (lambda ()
(set! src-col s-col)
(set! dest-col 0)
(out "; " comment-color))
0
qq?)
l))]
[(and (pair? (syntax-e c))
(eq? (syntax-e (car (syntax-e c))) 'code:line))
(let ([l (cdr (syntax->list c))])
(for-each (loop init-line! quote-depth qq?)
l))]
[(and (pair? (syntax-e c))
(eq? (syntax-e (car (syntax-e c))) 'code:hilite))
(let ([l (syntax->list c)]
[h? highlight?])
(unless (and l (= 2 (length l)))
(error "bad code:redex: ~e" (syntax->datum c)))
(advance c init-line!)
(set! src-col (syntax-column (cadr l)))
(hash-set! next-col-map src-col dest-col)
(set! highlight? #t)
((loop init-line! quote-depth qq?) (cadr l))
(set! highlight? h?)
(set! src-col (add1 src-col)))]
[(and (pair? (syntax-e c))
(eq? (syntax-e (car (syntax-e c))) 'code:quote))
(advance c init-line!)
(let ([quote-depth (to-quoted "`" qq? quote-depth out color? inc-src-col)])
(out "(" (if (positive? quote-depth) value-color paren-color))
(set! src-col (+ src-col 1))
(hash-set! next-col-map src-col dest-col)
((loop init-line! quote-depth qq?)
(datum->syntax #'here 'quote (car (syntax-e c))))
(for-each (loop init-line! (add1 quote-depth) qq?)
(cdr (syntax->list c)))
(out ")" (if (positive? quote-depth) value-color paren-color))
(set! src-col (+ src-col 1))
#;
(hash-set! next-col-map src-col dest-col))]
[(and (pair? (syntax-e c))
(memq (syntax-e (car (syntax-e c)))
'(quote quasiquote unquote unquote-splicing
quasisyntax syntax unsyntax unsyntax-splicing))
(let ([v (syntax->list c)])
(and v (= 2 (length v))))
(or (not qq?)
(quote-depth . > . 1)
(not (memq (syntax-e (car (syntax-e c)))
'(unquote unquote-splicing)))))
(advance c init-line!)
(let ([quote-depth (to-quoted "`" qq? quote-depth out color? inc-src-col)])
(let-values ([(str quote-delta)
(case (syntax-e (car (syntax-e c)))
[(quote) (values "'" +inf.0)]
[(unquote) (values "," -1)]
[(unquote-splicing) (values ",@" -1)]
[(quasiquote) (values "`" +1)]
[(syntax) (values "#'" 0)]
[(quasisyntax) (values "#`" 0)]
[(unsyntax) (values "#," 0)]
[(unsyntax-splicing) (values "#,@" 0)])])
(out str (if (positive? (+ quote-depth quote-delta))
value-color
reader-color))
(let ([i (cadr (syntax->list c))])
(set! src-col (or (syntax-column i) src-col))
(hash-set! next-col-map src-col dest-col)
((loop init-line! (+ quote-depth quote-delta) qq?) i))))]
[(and (pair? (syntax-e c))
(convert-infix c quote-depth qq?))
=> (lambda (converted)
((loop init-line! quote-depth qq?) converted))]
[(or (pair? (syntax-e c))
(null? (syntax-e c))
(vector? (syntax-e c))
(and (struct? (syntax-e c))
(prefab-struct-key (syntax-e c)))
(struct-proxy? (syntax-e c)))
(let* ([sh (or (syntax-property c 'paren-shape)
#\()]
[quote-depth (if (and (not qq?)
(zero? quote-depth)
(or (vector? (syntax-e c))
(struct? (syntax-e c))))
+inf.0
quote-depth)]
[p-color (if (positive? quote-depth)
value-color
(if (eq? sh #\?)
opt-color
paren-color))])
(advance c init-line!)
(let ([quote-depth (if (struct-proxy? (syntax-e c))
(to-unquoted qq? quote-depth out color? inc-src-col)
(to-quoted "`" qq? quote-depth out color? inc-src-col))])
(when (vector? (syntax-e c))
(let ([vec (syntax-e c)])
(out "#" #;(format "#~a" (vector-length vec)) p-color)
(if (zero? (vector-length vec))
(set! src-col (+ src-col (- (syntax-span c) 2)))
(set! src-col (+ src-col (- (syntax-column (vector-ref vec 0))
(syntax-column c)
1))))))
(when (struct? (syntax-e c))
(out "#s" p-color)
(set! src-col (+ src-col 2)))
(out (case sh
[(#\[ #\?) "["]
[(#\{) "{"]
[else "("])
p-color)
(set! src-col (+ src-col 1))
(hash-set! next-col-map src-col dest-col)
(let lloop ([l (cond
[(vector? (syntax-e c))
(vector->short-list (syntax-e c) syntax-e)]
[(struct? (syntax-e c))
(let ([l (vector->list (struct->vector (syntax-e c)))])
;; Need to build key datum, syntax-ize it internally, and
;; set the overall width to fit right:
(cons (let ([key (syntax-ize (prefab-struct-key (syntax-e c))
(+ 3 (or (syntax-column c) 0))
(or (syntax-line c) 1))]
[end (if (pair? (cdr l))
(and (equal? (syntax-line c) (syntax-line (cadr l)))
(syntax-column (cadr l)))
(and (syntax-column c)
(+ (syntax-column c) (syntax-span c))))])
(if end
(datum->syntax #f
(syntax-e key)
(vector #f (syntax-line key)
(syntax-column key)
(syntax-position key)
(- end 1 (syntax-column key))))
end))
(cdr l)))]
[(struct-proxy? (syntax-e c))
(cons
(struct-proxy-name (syntax-e c))
(struct-proxy-content (syntax-e c)))]
[else c])]
[first-qq? (and qq? (not (struct-proxy? (syntax-e c))))])
(cond
[(and (syntax? l)
(pair? (syntax-e l))
(not (and (memq (syntax-e (car (syntax-e l)))
'(quote unquote syntax unsyntax quasiquote quasiunsyntax))
(let ([v (syntax->list l)])
(and v (= 2 (length v))))
(or (not qq?)
(quote-depth . > . 1)
(not (memq (syntax-e (car (syntax-e l)))
'(unquote unquote-splicing)))))))
(lloop (syntax-e l) first-qq?)]
[(or (null? l)
(and (syntax? l)
(null? (syntax-e l))))
(void)]
[(pair? l)
((loop init-line! quote-depth first-qq?) (car l))
(lloop (cdr l) qq?)]
[else
(advance l init-line! -2)
(out ". " (if (positive? quote-depth) value-color paren-color))
(set! src-col (+ src-col 3))
(hash-set! next-col-map src-col dest-col)
((loop init-line! quote-depth first-qq?) l)]))
(out (case sh
[(#\[ #\?) "]"]
[(#\{) "}"]
[else ")"])
p-color)
(set! src-col (+ src-col 1))
#;
(hash-set! next-col-map src-col dest-col)))]
[(box? (syntax-e c))
(advance c init-line!)
(let ([quote-depth (to-quoted "`" qq? quote-depth out color? inc-src-col)])
(out "#&" value-color)
(set! src-col (+ src-col 2))
(hash-set! next-col-map src-col dest-col)
((loop init-line! (if qq? quote-depth +inf.0) qq?) (unbox (syntax-e c))))]
[(hash? (syntax-e c))
(advance c init-line!)
(let ([equal-table? (not (hash-eq? (syntax-e c)))]
[quote-depth (to-quoted "`" qq? quote-depth out color? inc-src-col)])
(out (if equal-table?
"#hash"
"#hasheq")
value-color)
(let ([delta (+ 5 (if equal-table? 2 0))]
[orig-col src-col])
(set! src-col (+ src-col delta))
(hash-set! next-col-map src-col dest-col)
((loop init-line! (if qq? quote-depth +inf.0) qq?)
(syntax-ize (hash-map (syntax-e c) cons)
(+ (syntax-column c) delta)))
(set! src-col (+ orig-col (syntax-span c)))))]
[(graph-reference? (syntax-e c))
(advance c init-line!)
(out (format "#~a#" (unbox (graph-reference-bx (syntax-e c))))
(if (positive? quote-depth)
value-color
paren-color))
(set! src-col (+ src-col (syntax-span c)))]
[(graph-defn? (syntax-e c))
(advance c init-line!)
(let ([bx (graph-defn-bx (syntax-e c))])
(out (format "#~a=" (unbox bx))
(if (positive? quote-depth)
value-color
paren-color))
(set! src-col (+ src-col 3))
((loop init-line! quote-depth qq?) (graph-defn-r (syntax-e c))))]
[else
(advance c init-line!)
(typeset-atom c out color? quote-depth qq?)
(set! src-col (+ src-col (or (syntax-span c) 1)))
#;
(hash-set! next-col-map src-col dest-col)])))
(out prefix1 #f)
(set! dest-col 0)
(hash-set! next-col-map init-col dest-col)
((loop (lambda () (set! src-col init-col) (set! dest-col 0)) 0 qq?) c)
(if (list? suffix)
(map (lambda (sfx)
(finish-line!)
(out sfx #f))
suffix)
(out suffix #f))
(unless (null? content)
(finish-line!))
(if multi-line?
(if (= 1 (length docs))
(car docs)
(make-table block-color (map list (reverse docs))))
(make-sized-element #f (reverse content) dest-col))))
(define (typeset c multi-line? prefix1 prefix suffix color? qq?)
(let* ([c (syntax-ize c 0 #:qq? qq?)]
[s (syntax-e c)])
(if (or multi-line?
(eq? 'code:blank s)
(pair? s)
(vector? s)
(struct? s)
(box? s)
(null? s)
(hash? s)
(graph-defn? s)
(graph-reference? s)
(struct-proxy? s))
(gen-typeset c multi-line? prefix1 prefix suffix color? qq?)
(typeset-atom c
(letrec ([mk
(case-lambda
[(elem color)
(mk elem color (or (syntax-span c) 1))]
[(elem color len)
(if (and (string? elem)
(= len (string-length elem)))
(make-element/cache (and color? color) elem)
(make-sized-element (and color? color) elem len))])])
mk)
color? 0 qq?))))
(define (to-element c #:qq? [qq? #f])
(typeset c #f "" "" "" #t qq?))
(define (to-element/no-color c #:qq? [qq? #f])
(typeset c #f "" "" "" #f qq?))
(define (to-paragraph c #:qq? [qq? #f])
(typeset c #t "" "" "" #t qq?))
(define ((to-paragraph/prefix pfx1 pfx sfx) c #:qq? [qq? #f])
(typeset c #t pfx1 pfx sfx #t qq?))
(begin-for-syntax
(define-struct variable-id (sym)
#:omit-define-syntaxes
#:property prop:procedure (lambda (self stx)
(raise-syntax-error
#f
(string-append
"misuse of an identifier (not in `scheme', etc.) that is"
" bound as a code-typesetting variable")
stx)))
(define-struct element-id-transformer (proc)
#:omit-define-syntaxes
#:property prop:procedure (lambda (self stx)
(raise-syntax-error
#f
(string-append
"misuse of an identifier (not in `scheme', etc.) that is"
" bound as an code-typesetting element transformer")
stx))))
(define-syntax (define-code stx)
(syntax-case stx ()
[(_ code typeset-code uncode d->s stx-prop)
(syntax/loc stx
(define-syntax (code stx)
(define (wrap-loc v ctx e)
`(,#'d->s ,ctx
,e
#(code
,(syntax-line v)
,(syntax-column v)
,(syntax-position v)
,(syntax-span v))))
(define (stx->loc-s-expr v)
(let ([slv (and (identifier? v)
(syntax-local-value v (lambda () #f)))])
(cond
[(variable-id? slv)
(wrap-loc v #f `(,#'make-var-id ',(variable-id-sym slv)))]
[(element-id-transformer? slv)
(wrap-loc v #f ((element-id-transformer-proc slv) v))]
[(syntax? v)
(let ([mk (wrap-loc
v
`(quote-syntax ,(datum->syntax v 'defcode))
(syntax-case v (uncode)
[(uncode e) #'e]
[else (stx->loc-s-expr (syntax-e v))]))])
(let ([prop (syntax-property v 'paren-shape)])
(if prop
`(,#'stx-prop ,mk 'paren-shape ,prop)
mk)))]
[(null? v) 'null]
[(list? v) `(list . ,(map stx->loc-s-expr v))]
[(pair? v) `(cons ,(stx->loc-s-expr (car v))
,(stx->loc-s-expr (cdr v)))]
[(vector? v) `(vector ,@(map
stx->loc-s-expr
(vector->list v)))]
[(and (struct? v) (prefab-struct-key v))
`(make-prefab-struct (quote ,(prefab-struct-key v))
,@(map
stx->loc-s-expr
(cdr (vector->list (struct->vector v)))))]
[(box? v) `(box ,(stx->loc-s-expr (unbox v)))]
[else `(quote ,v)])))
(define (cvt s)
(datum->syntax #'here (stx->loc-s-expr s) #f))
(if (eq? (syntax-local-context) 'expression)
(syntax-case stx ()
[(_ expr) #`(typeset-code #,(cvt #'expr))]
[(_ expr (... ...))
#`(typeset-code #,(cvt #'(code:line expr (... ...))))])
(quasisyntax/loc stx
(#%expression #,stx)))))]
[(_ code typeset-code uncode d->s)
#'(define-code code typeset-code uncode d->s syntax-property)]
[(_ code typeset-code uncode)
#'(define-code code typeset-code uncode datum->syntax syntax-property)]
[(_ code typeset-code) #'(define-code code typeset-code unsyntax)]))
(define syntax-ize-hook (make-parameter (lambda (v col) #f)))
(define (vector->short-list v extract)
(vector->list v)
#;
(let ([l (vector->list v)])
(reverse (list-tail
(reverse l)
(- (vector-length v)
(let loop ([i (sub1 (vector-length v))])
(cond
[(zero? i) 1]
[(eq? (extract (vector-ref v i))
(extract (vector-ref v (sub1 i))))
(loop (sub1 i))]
[else (add1 i)])))))))
(define (short-list->vector v l)
(list->vector
(let ([n (length l)])
(if (n . < . (vector-length v))
(reverse (let loop ([r (reverse l)][i (- (vector-length v) n)])
(if (zero? i)
r
(loop (cons (car r) r) (sub1 i)))))
l))))
(define-struct var-id (sym))
(define-struct shaped-parens (val shape))
(define-struct just-context (val ctx))
(define-struct alternate-display (id string))
(define-struct literal-syntax (stx))
(define-struct struct-proxy (name content))
(define-struct graph-reference (bx))
(define-struct graph-defn (r bx))
(define (syntax-ize v col [line 1] #:qq? [qq? #f])
(do-syntax-ize v col line (box #hasheq()) #f (and qq? 0)))
(define (graph-count ht graph?)
(and graph?
(let ([n (hash-ref (unbox ht) '#%graph-count 0)])
(set-box! ht (hash-set (unbox ht) '#%graph-count (add1 n)))
n)))
(define (do-syntax-ize v col line ht graph? qq)
(cond
[((syntax-ize-hook) v col)
=> (lambda (r) r)]
[(shaped-parens? v)
(syntax-property (do-syntax-ize (shaped-parens-val v) col line ht #f qq)
'paren-shape
(shaped-parens-shape v))]
[(just-context? v)
(let ([s (do-syntax-ize (just-context-val v) col line ht #f qq)])
(datum->syntax (just-context-ctx v)
(syntax-e s)
s
s
(just-context-ctx v)))]
[(alternate-display? v)
(let ([s (do-syntax-ize (alternate-display-id v) col line ht #f qq)])
(syntax-property s
'display-string
(alternate-display-string v)))]
[(hash-ref (unbox ht) v #f)
=> (lambda (m)
(unless (unbox m)
(set-box! m #t))
(datum->syntax #f
(make-graph-reference m)
(vector #f line col (+ 1 col) 1)))]
[(and (list? v)
(pair? v)
(let ([s (let ([s (car v)])
(if (just-context? s)
(just-context-val s)
s))])
(and
(or (memq s '(quaisquote quote))
(and (memq s '(unquote unquote-splicing))
(or (not qq)
(qq . > . 2))))
s)))
=> (lambda (s)
(let ([c (do-syntax-ize (cadr v) (+ col 1) line ht #f qq)])
(datum->syntax #f
(list (do-syntax-ize (car v) col line ht #f
(and qq
(case s
[(quaisquote) (add1 qq)]
[(unquote unquote-splicing) (sub1 qq)]
[else qq])))
c)
(vector #f line col (+ 1 col)
(+ 1 (syntax-span c))))))]
[(or (list? v)
(vector? v)
(and (struct? v)
(or (and qq
;; Watch out for partially transparent subtypes of `element':
(not (element? v)))
(prefab-struct-key v))))
(let ([orig-ht (unbox ht)]
[graph-box (box (graph-count ht graph?))]
[qq (and qq (max 1 qq))])
(set-box! ht (hash-set (unbox ht) v graph-box))
(let* ([graph-sz (if graph?
(+ 2 (string-length (format "~a" (unbox graph-box))))
0)]
[vec-sz (cond
[(vector? v)
(+ 1 #;(string-length (format "~a" (vector-length v))))]
[(struct? v)
(if (prefab-struct-key v)
2
0)]
[else 0])]
[r (let ([l (let loop ([col (+ col 1 vec-sz graph-sz)]
[v (cond
[(vector? v)
(vector->short-list v values)]
[(struct? v)
(cons (let ([pf (prefab-struct-key v)])
(if pf
(prefab-struct-key v)
(object-name v)))
(cdr (vector->list (struct->vector v))))]
[else v])])
(if (null? v)
null
(let ([i (do-syntax-ize (car v) col line ht #f qq)])
(cons i
(loop (+ col 1 (syntax-span i)) (cdr v))))))])
(datum->syntax #f
(cond
[(vector? v) (short-list->vector v l)]
[(struct? v)
(let ([pf (prefab-struct-key v)])
(if pf
(apply make-prefab-struct (prefab-struct-key v) (cdr l))
(make-struct-proxy (car l) (cdr l))))]
[else l])
(vector #f line
(+ graph-sz col)
(+ 1 graph-sz col)
(+ 2
vec-sz
(if (zero? (length l))
0
(sub1 (length l)))
(apply + (map syntax-span l))))))])
(unless graph?
(set-box! ht (hash-set (unbox ht) v #f)))
(cond
[graph? (datum->syntax #f
(make-graph-defn r graph-box)
(vector #f (syntax-line r)
(- (syntax-column r) graph-sz)
(- (syntax-position r) graph-sz)
(+ (syntax-span r) graph-sz)))]
[(unbox graph-box)
;; Go again, this time knowing that there will be a graph:
(set-box! ht orig-ht)
(do-syntax-ize v col line ht #t qq)]
[else r])))]
[(pair? v)
(let ([orig-ht (unbox ht)]
[graph-box (box (graph-count ht graph?))]
[qq (and qq (max 1 qq))])
(set-box! ht (hash-set (unbox ht) v graph-box))
(let* ([inc (if graph?
(+ 2 (string-length (format "~a" (unbox graph-box))))
0)]
[a (do-syntax-ize (car v) (+ col 1 inc) line ht #f qq)]
[sep (if (and (pair? (cdr v))
;; FIXME: what if it turns out to be a graph reference?
(not (hash-ref (unbox ht) (cdr v) #f)))
0
3)]
[b (do-syntax-ize (cdr v) (+ col 1 inc (syntax-span a) sep) line ht #f qq)])
(let ([r (datum->syntax #f
(cons a b)
(vector #f line (+ col inc) (+ 1 col inc)
(+ 2 sep (syntax-span a) (syntax-span b))))])
(unless graph?
(set-box! ht (hash-set (unbox ht) v #f)))
(cond
[graph? (datum->syntax #f
(make-graph-defn r graph-box)
(vector #f line col (+ 1 col)
(+ inc (syntax-span r))))]
[(unbox graph-box)
;; Go again...
(set-box! ht orig-ht)
(do-syntax-ize v col line ht #t qq)]
[else r]))))]
[(box? v)
(let ([a (do-syntax-ize (unbox v) (+ col 2) line ht #f (and qq (max 1 qq)))])
(datum->syntax #f
(box a)
(vector #f line col (+ 1 col)
(+ 2 (syntax-span a)))))]
[else
(datum->syntax #f v (vector #f line col (+ 1 col) 1))])))

View File

@ -8,11 +8,12 @@ through a textbook:
@itemize[ @itemize[
@item{@italic{@link["http:///www.htdp.org/"]{How to @item{@italic{@link["http:///www.htdp.org/"]{How to Design Programs}}
Design Programs}} is the best place to start.} is the best place to start. Whenever the book says ``Scheme,''
you can read it as ``Racket.''}
@item{@other-manual['(lib "web-server/scribblings/tutorial/continue.scrbl")] @item{@other-manual['(lib "web-server/scribblings/tutorial/continue.scrbl")]
introduces you to the Module language and building web applications.} introduces you to modules and building web applications.}
@item{@other-manual['(lib "scribblings/guide/guide.scrbl")] describes @item{@other-manual['(lib "scribblings/guide/guide.scrbl")] describes
the rest of the Racket language, which is much bigger than the rest of the Racket language, which is much bigger than

View File

@ -1,6 +1,6 @@
#lang scribble/doc #lang scribble/doc
@(require scribble/struct @(require scribble/struct
scribble/scheme scribble/racket
(for-syntax racket/base) (for-syntax racket/base)
"mz.ss" "mz.ss"
"prog-steps.ss") "prog-steps.ss")
@ -11,13 +11,13 @@
@(define *redex (lambda (c) @(define *redex (lambda (c)
(make-element highlighted-color (list c)))) (make-element highlighted-color (list c))))
@(define-syntax redex @(define-syntax redex
(syntax-rules () [(_ a) (*redex (scheme a))])) (syntax-rules () [(_ a) (*redex (racket a))]))
@(define hole (make-element #f (list "[]"))) @(define hole (make-element #f (list "[]")))
@(define (*sub c e) (make-element #f (list c "[" e "]"))) @(define (*sub c e) (make-element #f (list c "[" e "]")))
@(define-syntax sub @(define-syntax sub
(syntax-rules () [(_ a b) (*sub (scheme a) (scheme b))])) (syntax-rules () [(_ a b) (*sub (racket a) (racket b))]))
@(define (frame n) @(define (frame n)
(make-element variable-color (make-element variable-color
(list "C" (make-element 'subscript (list (format "~a" n)))))) (list "C" (make-element 'subscript (list (format "~a" n))))))
@ -29,21 +29,21 @@ to switch to the usual langle/rangle that is used in syntax definitions.
@(define comma (make-element 'tt (list ", "))) @(define comma (make-element 'tt (list ", ")))
@(define (*state c e) (make-element #f (list langle c comma e rangle))) @(define (*state c e) (make-element #f (list langle c comma e rangle)))
@(define-syntax state @(define-syntax state
(syntax-rules () [(_ a b) (*state (scheme a) (scheme b))])) (syntax-rules () [(_ a b) (*state (racket a) (racket b))]))
;} ;}
@;------------------------------------------------------------------------ @;------------------------------------------------------------------------
@title[#:tag "eval-model"]{Evaluation Model} @title[#:tag "eval-model"]{Evaluation Model}
Scheme evaluation can be viewed as the simplification of expressions Racket evaluation can be viewed as the simplification of expressions
to obtain values. For example, just as an elementary-school student to obtain values. For example, just as an elementary-school student
simplifies simplifies
@verbatim{ 1 + 1 = 2} @verbatim{ 1 + 1 = 2}
Scheme evaluation simplifies Racket evaluation simplifies
@schemeblock[ @racketblock[
(+ 1 1) @#,reduces 2 (+ 1 1) @#,reduces 2
] ]
@ -51,14 +51,14 @@ The arrow @reduces above replaces the more traditional @tt{=} to
emphasize that evaluation proceeds in a particular direction towards emphasize that evaluation proceeds in a particular direction towards
simpler expressions. In particular, a @deftech{value} is an simpler expressions. In particular, a @deftech{value} is an
expression that evaluation simplifies no further, such as the number expression that evaluation simplifies no further, such as the number
@scheme[2]. @racket[2].
@;------------------------------------------------------------------------ @;------------------------------------------------------------------------
@section[#:tag "cont-model"]{Sub-expression Evaluation and Continuations} @section[#:tag "cont-model"]{Sub-expression Evaluation and Continuations}
Some simplifications require more than one step. For example: Some simplifications require more than one step. For example:
@schemeblock[ @racketblock[
(- 4 #,(redex (+ 1 1))) #,reduces #,(redex (- 4 2)) #,reduces 2 (- 4 #,(redex (+ 1 1))) #,reduces #,(redex (- 4 2)) #,reduces 2
] ]
@ -66,15 +66,15 @@ An expression that is not a @tech{value} can always be partitioned
into two parts: a @deftech{redex}, which is the part that changed in a into two parts: a @deftech{redex}, which is the part that changed in a
single-step simplification (highlighted), and the single-step simplification (highlighted), and the
@deftech{continuation}, which is the surrounding expression @deftech{continuation}, which is the surrounding expression
context. In @scheme[(- 4 (+ 1 1))], the redex is @scheme[(+ 1 1)], and context. In @racket[(- 4 (+ 1 1))], the redex is @racket[(+ 1 1)], and
the continuation is @scheme[(- 4 @#,hole)], where @hole takes the the continuation is @racket[(- 4 @#,hole)], where @hole takes the
place of the redex. That is, the continuation says how to ``continue'' place of the redex. That is, the continuation says how to ``continue''
after the @tech{redex} is reduced to a @tech{value}. after the @tech{redex} is reduced to a @tech{value}.
Before some things can be evaluated, some sub-expressions must be Before some things can be evaluated, some sub-expressions must be
evaluated; for example, in the application @scheme[(- 4 (+ 1 1))], the evaluated; for example, in the application @racket[(- 4 (+ 1 1))], the
application of @scheme[-] cannot be reduced until the sub-expression application of @racket[-] cannot be reduced until the sub-expression
@scheme[(+ 1 1)] is reduced. @racket[(+ 1 1)] is reduced.
Thus, the specification of each syntactic form specifies how (some of) Thus, the specification of each syntactic form specifies how (some of)
its sub-expressions are evaluated, and then how the results are its sub-expressions are evaluated, and then how the results are
@ -86,65 +86,65 @@ evaluation steps during which an expression contains the @tech{redex}.
@;------------------------------------------------------------------------ @;------------------------------------------------------------------------
@section{Tail Position} @section{Tail Position}
An expression @scheme[_expr1] is in @deftech{tail position} with An expression @racket[_expr1] is in @deftech{tail position} with
respect to an enclosing expression @scheme[_expr2] if, whenever respect to an enclosing expression @racket[_expr2] if, whenever
@scheme[_expr1] becomes a redex, its @tech{continuation} is the same @racket[_expr1] becomes a redex, its @tech{continuation} is the same
as was the enclosing @scheme[_expr2]'s @tech{continuation}. as was the enclosing @racket[_expr2]'s @tech{continuation}.
For example, the @scheme[(+ 1 1)] expression is @italic{not} in @tech{tail For example, the @racket[(+ 1 1)] expression is @italic{not} in @tech{tail
position} with respect to @scheme[(- 4 (+ 1 1))]. To illustrate, we use position} with respect to @racket[(- 4 (+ 1 1))]. To illustrate, we use
the notation @sub[_C _expr] to mean the expression that is produced by the notation @sub[_C _expr] to mean the expression that is produced by
substituting @scheme[_expr] in place of @hole in the @tech{continuation} substituting @racket[_expr] in place of @hole in the @tech{continuation}
@scheme[_C]: @racket[_C]:
@schemeblock[ @racketblock[
@#,sub[_C (- 4 (+ 1 1))] @#,reduces @#,sub[_C (- 4 2)] @#,sub[_C (- 4 (+ 1 1))] @#,reduces @#,sub[_C (- 4 2)]
] ]
In this case, the @tech{continuation} for reducing @scheme[(+ 1 1)] is In this case, the @tech{continuation} for reducing @racket[(+ 1 1)] is
@sub[_C (+ 4 @#,hole)], not just @scheme[_C]. @sub[_C (+ 4 @#,hole)], not just @racket[_C].
In contrast, @scheme[(+ 1 1)] is in @tech{tail position} with respect In contrast, @racket[(+ 1 1)] is in @tech{tail position} with respect
to @scheme[(if (zero? 0) (+ 1 1) 3)], because, for any continuation to @racket[(if (zero? 0) (+ 1 1) 3)], because, for any continuation
@scheme[_C], @racket[_C],
@schemeblock[ @racketblock[
@#,sub[_C (if (zero? 0) (+ 1 1) 3)] @#,reduces @#,sub[_C (if #t (+ 1 1) 3)] @#,reduces @#,sub[_C (+ 1 1)] @#,sub[_C (if (zero? 0) (+ 1 1) 3)] @#,reduces @#,sub[_C (if #t (+ 1 1) 3)] @#,reduces @#,sub[_C (+ 1 1)]
] ]
The steps in this reduction sequence are driven by the definition of The steps in this reduction sequence are driven by the definition of
@scheme[if], and they do not depend on the @tech{continuation} @racket[if], and they do not depend on the @tech{continuation}
@scheme[_C]. The ``then'' branch of an @scheme[if] form is always in @racket[_C]. The ``then'' branch of an @racket[if] form is always in
@tech{tail position} with respect to the @scheme[if] form. Due to a @tech{tail position} with respect to the @racket[if] form. Due to a
similar reduction rule for @scheme[if] and @scheme[#f], the ``else'' similar reduction rule for @racket[if] and @racket[#f], the ``else''
branch of an @scheme[if] form is also in @tech{tail position}. branch of an @racket[if] form is also in @tech{tail position}.
@tech{Tail-position} specifications provide a guarantee about the @tech{Tail-position} specifications provide a guarantee about the
asymptotic space consumption of a computation. In general, the asymptotic space consumption of a computation. In general, the
specification of @tech{tail positions} goes with each syntactic form, specification of @tech{tail positions} goes with each syntactic form,
like @scheme[if]. like @racket[if].
@;------------------------------------------------------------------------ @;------------------------------------------------------------------------
@section[#:tag "values-model"]{Multiple Return Values} @section[#:tag "values-model"]{Multiple Return Values}
A Scheme expression can evaluate to @deftech{multiple values}, in the A Racket expression can evaluate to @deftech{multiple values}, in the
same way that a procedure can accept multiple arguments. same way that a procedure can accept multiple arguments.
Most @tech{continuations} expect a particular number of result Most @tech{continuations} expect a particular number of result
@tech{values}. Indeed, most @tech{continuations}, such as @scheme[(+ @tech{values}. Indeed, most @tech{continuations}, such as @racket[(+
@#,hole 1)] expect a single @tech{value}. The @tech{continuation} @#,hole 1)] expect a single @tech{value}. The @tech{continuation}
@scheme[(let-values ([(x y) @#,hole]) _expr)] expects two result @racket[(let-values ([(x y) @#,hole]) _expr)] expects two result
@tech{values}; the first result replaces @scheme[x] in the body @tech{values}; the first result replaces @racket[x] in the body
@scheme[_expr], and the second replaces @scheme[y] in @racket[_expr], and the second replaces @racket[y] in
@scheme[_expr]. The @tech{continuation} @scheme[(begin @#,hole (+ 1 @racket[_expr]. The @tech{continuation} @racket[(begin @#,hole (+ 1
2))] accepts any number of result @tech{values}, because it ignores 2))] accepts any number of result @tech{values}, because it ignores
the result(s). the result(s).
In general, the specification of a syntactic form inidicates the In general, the specification of a syntactic form inidicates the
number of @tech{values} that it produces and the number that it number of @tech{values} that it produces and the number that it
expects from each of its sub-expression. In addtion, some procedures expects from each of its sub-expression. In addtion, some procedures
(notably @scheme[values]) produce multiple @tech{values}, and some (notably @racket[values]) produce multiple @tech{values}, and some
procedures (notably @scheme[call-with-values]) create continuations procedures (notably @racket[call-with-values]) create continuations
internally that accept a certain number of @tech{values}. internally that accept a certain number of @tech{values}.
@;------------------------------------------------------------------------ @;------------------------------------------------------------------------
@ -158,28 +158,28 @@ then an algebra student simplifies @tt{x + 1} as follows:
@verbatim{ x + 1 = 10 + 1 = 11} @verbatim{ x + 1 = 10 + 1 = 11}
Scheme works much the same way, in that a set of @tech{top-level Racket works much the same way, in that a set of @tech{top-level
variables} are available for substitutions on demand during variables} are available for substitutions on demand during
evaluation. For example, given evaluation. For example, given
@schemeblock[ @racketblock[
(define x 10) (define x 10)
] ]
then then
@schemeblock[ @racketblock[
#,(redex (+ x 1)) #,reduces #,(redex (+ 10 1)) #,reduces 11 #,(redex (+ x 1)) #,reduces #,(redex (+ 10 1)) #,reduces 11
] ]
In Scheme, the way definitions appear is just as important as the way In Racket, the way definitions appear is just as important as the way
that they are used. Scheme evaluation thus keeps track of both that they are used. Racket evaluation thus keeps track of both
definitions and the current expression, and it extends the set of definitions and the current expression, and it extends the set of
definitions in response to evaluating forms such as @scheme[define]. definitions in response to evaluating forms such as @racket[define].
Each evaluation step, then, takes the current set of definitions and Each evaluation step, then, takes the current set of definitions and
program to a new set of definitions and program. Before a program to a new set of definitions and program. Before a
@scheme[define] can be moved into the set of definitions, its @racket[define] can be moved into the set of definitions, its
right-hand expression must be reduced to a @tech{value}. right-hand expression must be reduced to a @tech{value}.
@prog-steps/no-obj[ @prog-steps/no-obj[
@ -197,7 +197,7 @@ right-hand expression must be reduced to a @tech{value}.
11] 11]
] ]
Using @scheme[set!], a program can change the value associated with an Using @racket[set!], a program can change the value associated with an
existing @tech{top-level variable}: existing @tech{top-level variable}:
@prog-steps/no-obj[ @prog-steps/no-obj[
@ -214,9 +214,9 @@ existing @tech{top-level variable}:
@;------------------------------------------------------------------------ @;------------------------------------------------------------------------
@section{Objects and Imperative Update} @section{Objects and Imperative Update}
In addition to @scheme[set!] for imperative update of @tech{top-level In addition to @racket[set!] for imperative update of @tech{top-level
variables}, various procedures enable the modification of elements variables}, various procedures enable the modification of elements
within a compound data structure. For example, @scheme[vector-set!] within a compound data structure. For example, @racket[vector-set!]
modifies the content of a vector. modifies the content of a vector.
To allow such modifications to data, we must distingiush between To allow such modifications to data, we must distingiush between
@ -224,16 +224,16 @@ To allow such modifications to data, we must distingiush between
@deftech{objects}, which hold the data referenced by a value. @deftech{objects}, which hold the data referenced by a value.
A few kinds of @tech{objects} can serve directly as values, including A few kinds of @tech{objects} can serve directly as values, including
booleans, @scheme[(void)], and small exact integers. More generally, booleans, @racket[(void)], and small exact integers. More generally,
however, a @tech{value} is a reference to an @tech{object}. For however, a @tech{value} is a reference to an @tech{object}. For
example, a @tech{value} can be a reference to a particular vector that example, a @tech{value} can be a reference to a particular vector that
currently holds the value @scheme[10] in its first slot. If an currently holds the value @racket[10] in its first slot. If an
@tech{object} is modified, then the modification is visible through @tech{object} is modified, then the modification is visible through
all copies of the @tech{value} that reference the same @tech{object}. all copies of the @tech{value} that reference the same @tech{object}.
In the evaluation model, a set of @tech{objects} must be carried along In the evaluation model, a set of @tech{objects} must be carried along
with each step in evaluation, just like the definition set. Operations with each step in evaluation, just like the definition set. Operations
that create @tech{objects}, such as @scheme[vector], add to the set of that create @tech{objects}, such as @racket[vector], add to the set of
@tech{objects}: @tech{objects}:
@prog-steps[ @prog-steps[
@ -306,35 +306,35 @@ reference is crucial. A @tech{top-level variable} is not a
value is extracted from the current set of definitions. An object value is extracted from the current set of definitions. An object
reference, in contrast is a value, and therefore needs no further reference, in contrast is a value, and therefore needs no further
evaluation. The model evaluation steps above use angle-bracketed evaluation. The model evaluation steps above use angle-bracketed
@scheme[<o1>] for an object reference to distinguish it from a @racket[<o1>] for an object reference to distinguish it from a
@tech{variable} name. @tech{variable} name.
A direct object reference can never appear in a text-based source A direct object reference can never appear in a text-based source
program. A program representation created with program. A program representation created with
@scheme[datum->syntax-object], however, can embed direct references to @racket[datum->syntax], however, can embed direct references to
existing @tech{objects}. existing @tech{objects}.
@;------------------------------------------------------------------------ @;------------------------------------------------------------------------
@section[#:tag "model-eq"]{Object Identity and Comparisons} @section[#:tag "model-eq"]{Object Identity and Comparisons}
The @scheme[eq?] operator compares two @tech{values}, returning The @racket[eq?] operator compares two @tech{values}, returning
@scheme[#t] when the values refer to the same @tech{object}. This form @racket[#t] when the values refer to the same @tech{object}. This form
of equality is suitable for comparing objects that support imperative of equality is suitable for comparing objects that support imperative
update (e.g., to determine that the effect of modifying an object update (e.g., to determine that the effect of modifying an object
through one reference is visible through another reference). Also, an through one reference is visible through another reference). Also, an
@scheme[eq?] test evaluates quickly, and @scheme[eq?]-based hashing @racket[eq?] test evaluates quickly, and @racket[eq?]-based hashing
is more lightweight than @scheme[equal?]-based hashing in hash tables. is more lightweight than @racket[equal?]-based hashing in hash tables.
In some cases, however, @scheme[eq?] is unsuitable as a comparison In some cases, however, @racket[eq?] is unsuitable as a comparison
operator, because the generation of @tech{objects} is not clearly operator, because the generation of @tech{objects} is not clearly
defined. In particular, two applications of @scheme[+] to the same two defined. In particular, two applications of @racket[+] to the same two
exact integers may or may not produce results that are @scheme[eq?], exact integers may or may not produce results that are @racket[eq?],
although the results are always @scheme[equal?]. Similarly, evaluation although the results are always @racket[equal?]. Similarly, evaluation
of a @scheme[lambda] form typically generates a new procedure of a @racket[lambda] form typically generates a new procedure
@tech{object}, but it may re-use a procedure @tech{object} previously @tech{object}, but it may re-use a procedure @tech{object} previously
generated by the same source @scheme[lambda] form. generated by the same source @racket[lambda] form.
The behavior of a datatype with respect to @scheme[eq?] is generally The behavior of a datatype with respect to @racket[eq?] is generally
specified with the datatype and its associated procedures. specified with the datatype and its associated procedures.
@;------------------------------------------------------------------------ @;------------------------------------------------------------------------
@ -352,9 +352,9 @@ In the program state
(+ 1 x)] (+ 1 x)]
] ]
evaluation cannot depend on @scheme[<o2>], because it is not part of evaluation cannot depend on @racket[<o2>], because it is not part of
the program to evaluate, and it is not referenced by any definition the program to evaluate, and it is not referenced by any definition
that is accessible in the program. The @tech{object} @scheme[<o2>] may that is accessible in the program. The @tech{object} @racket[<o2>] may
therefore be removed from the evaluation by @deftech{garbage therefore be removed from the evaluation by @deftech{garbage
collection}. collection}.
@ -364,17 +364,17 @@ collector in determining which @tech{objects} are reachable for the
remainder of the computation. If an @tech{object} is reachable only remainder of the computation. If an @tech{object} is reachable only
via a @tech{weak reference}, then the object can be reclaimed, and the via a @tech{weak reference}, then the object can be reclaimed, and the
@tech{weak reference} is replaced by a different @tech{value} @tech{weak reference} is replaced by a different @tech{value}
(typically @scheme[#f]). (typically @racket[#f]).
As a special case, a @tech{fixnum} is always considered reachable by As a special case, a @tech{fixnum} is always considered reachable by
the garbage collector. Many other values are always reachable due to the garbage collector. Many other values are always reachable due to
the way they are implemented and used: A @tech{character} in the the way they are implemented and used: A @tech{character} in the
Latin-1 range is always reachable, because @scheme[equal?] Latin-1 Latin-1 range is always reachable, because @racket[equal?] Latin-1
characters are always @scheme[eq?], and all of the Latin-1 characters characters are always @racket[eq?], and all of the Latin-1 characters
are referenced by an internal module. Similarly, @scheme[null], are referenced by an internal module. Similarly, @racket[null],
@scheme[#t], @scheme[#f], @scheme[eof], and @|void-const| and are @racket[#t], @racket[#f], @racket[eof], and @|void-const| and are
always reachable. Values produced by @scheme[quote] remain reachable always reachable. Values produced by @racket[quote] remain reachable
when the @scheme[quote] expression itself is reachable. when the @racket[quote] expression itself is reachable.
@;------------------------------------------------------------------------ @;------------------------------------------------------------------------
@section{Procedure Applications and Local Variables} @section{Procedure Applications and Local Variables}
@ -391,8 +391,8 @@ The key step in this simplification is take the body of the defined
function @tt{f}, and then replace each @tt{x} with the actual function @tt{f}, and then replace each @tt{x} with the actual
@tech{value} @tt{1}. @tech{value} @tt{1}.
Scheme procedure application works much the same way. A procedure is Racket procedure application works much the same way. A procedure is
an @tech{object}, so evaluating @scheme[(f 7)] starts with a an @tech{object}, so evaluating @racket[(f 7)] starts with a
@tech{variable} lookup: @tech{variable} lookup:
@prog-steps[ @prog-steps[
@ -406,9 +406,9 @@ an @tech{object}, so evaluating @scheme[(f 7)] starts with a
Unlike in algebra, however, the @tech{value} associated with an Unlike in algebra, however, the @tech{value} associated with an
argument can be changed in the body of a procedure by using argument can be changed in the body of a procedure by using
@scheme[set!], as in the example @scheme[(lambda (x) (begin (set! x 3) @racket[set!], as in the example @racket[(lambda (x) (begin (set! x 3)
x))]. Since the @tech{value} associated with @scheme[x] can be x))]. Since the @tech{value} associated with @racket[x] can be
changed, an actual value for cannot be substituted for @scheme[x] when changed, an actual value for cannot be substituted for @racket[x] when
the procedure is applied. the procedure is applied.
Instead, a new @deftech{location} is created for each @tech{variable} Instead, a new @deftech{location} is created for each @tech{variable}
@ -439,10 +439,10 @@ a @tech{location} is generated, it (conceptually) uses a name that has
not been used before and that cannot not be generated again or not been used before and that cannot not be generated again or
accessed directly. accessed directly.
Generating a @tech{location} in this way means that @scheme[set!] Generating a @tech{location} in this way means that @racket[set!]
evaluates for @tech{local variables} in the same way as for evaluates for @tech{local variables} in the same way as for
@tech{top-level variables}, because the @tech{local variable} is @tech{top-level variables}, because the @tech{local variable} is
always replaced with a @tech{location} by the time the @scheme[set!] always replaced with a @tech{location} by the time the @racket[set!]
form is evaluated: form is evaluated:
@prog-steps[ @prog-steps[
@ -472,16 +472,16 @@ form is evaluated:
The substitution and @tech{location}-generation step of procedure The substitution and @tech{location}-generation step of procedure
application requires that the argument is a @tech{value}. Therefore, application requires that the argument is a @tech{value}. Therefore,
in @scheme[((lambda (x) (+ x 10)) (+ 1 2))], the @scheme[(+ 1 2)] in @racket[((lambda (x) (+ x 10)) (+ 1 2))], the @racket[(+ 1 2)]
sub-expression must be simplified to the @tech{value} @scheme[3], and sub-expression must be simplified to the @tech{value} @racket[3], and
then @scheme[3] can be placed into a @tech{location} for then @racket[3] can be placed into a @tech{location} for
@scheme[x]. In other words, Scheme is a @deftech{call-by-value} @racket[x]. In other words, Racket is a @deftech{call-by-value}
language. language.
Evaluation of a local-variable form, such as @scheme[(let ([x (+ 1 Evaluation of a local-variable form, such as @racket[(let ([x (+ 1
2)]) _expr)], is the same as for a procedure call. After @scheme[(+ 1 2)]) _expr)], is the same as for a procedure call. After @racket[(+ 1
2)] produces a @tech{value}, it is stored in a fresh @tech{location} 2)] produces a @tech{value}, it is stored in a fresh @tech{location}
that replaces every instance of @scheme[x] in @scheme[_expr]. that replaces every instance of @racket[x] in @racket[_expr].
@;------------------------------------------------------------------------ @;------------------------------------------------------------------------
@section{Variables and Locations} @section{Variables and Locations}
@ -498,20 +498,20 @@ through different instantiations.
For example, in the program For example, in the program
@schemeblock[(define y (+ (let ([x 5]) x) 6))] @racketblock[(define y (+ (let ([x 5]) x) 6))]
both @scheme[y] and @scheme[x] are @tech{variables}. The @scheme[y] both @racket[y] and @racket[x] are @tech{variables}. The @racket[y]
@tech{variable} is a @tech{top-level variable}, and the @scheme[x] is @tech{variable} is a @tech{top-level variable}, and the @racket[x] is
a @tech{local variable}. When this code is evaluated, a a @tech{local variable}. When this code is evaluated, a
@tech{location} is created for @scheme[x] to hold the value @tech{location} is created for @racket[x] to hold the value
@scheme[5], and a @tech{location} is also created for @scheme[y] to @racket[5], and a @tech{location} is also created for @racket[y] to
hold the value @scheme[6]. hold the value @racket[6].
The replacement of a @tech{variable} with a @tech{location} during The replacement of a @tech{variable} with a @tech{location} during
evaluation implements Scheme's @deftech{lexical scoping}. For example, evaluation implements Racket's @deftech{lexical scoping}. For example,
when a procedure-argument @tech{variable} @scheme[x] is replaced by when a procedure-argument @tech{variable} @racket[x] is replaced by
the @tech{location} @scheme[xloc], then it is replaced throughout the the @tech{location} @racket[xloc], then it is replaced throughout the
body of the procedure, including with any nested @scheme[lambda] body of the procedure, including with any nested @racket[lambda]
forms. As a result, future references of the @tech{variable} always forms. As a result, future references of the @tech{variable} always
access the same @tech{location}. access the same @tech{location}.
@ -520,7 +520,7 @@ access the same @tech{location}.
@margin-note/ref{See @secref["module"] for the syntax of modules.} @margin-note/ref{See @secref["module"] for the syntax of modules.}
Most definitions in PLT Scheme are in modules. In terms of evaluation, Most definitions in Racket 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. That is, a @deftech{module-level modules can define the name. That is, a @deftech{module-level
variable} is like a @tech{top-level variable} from the perspective of variable} is like a @tech{top-level variable} from the perspective of
@ -528,57 +528,57 @@ evaluation.
One difference between a module and a top-level definition is that a One difference between a module and 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
definitions. Evaluation of a @scheme[require] @deftech{instantiates} definitions. Evaluation of a @racket[require] @deftech{instantiates}
(i.e., triggers the @deftech{instantiation} of) a declared module, (i.e., triggers the @deftech{instantiation} of) a declared module,
which creates variables that correspond to its module-level which creates variables that correspond to its module-level
definitions. definitions.
For example, given the module declaration For example, given the module declaration
@schemeblock[ @racketblock[
(module m scheme (module m racket
(define x 10)) (define x 10))
] ]
the evaluation of @scheme[(require m)] creates the variable @scheme[x] the evaluation of @racket[(require m)] creates the variable @racket[x]
and installs @scheme[10] as its value. This @scheme[x] is unrelated to and installs @racket[10] as its value. This @racket[x] is unrelated to
any top-level definition of @scheme[x]. any top-level definition of @racket[x].
@;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@subsection[#:tag "module-phase"]{Phases} @subsection[#:tag "module-phase"]{Phases}
A module can be @tech{instantiate}d in multiple @deftech{phases}. A A module can be @tech{instantiate}d in multiple @deftech{phases}. A
phase is an integer that, again, is effectively a prefix on the names phase is an integer that, again, is effectively a prefix on the names
of module-level definitions. A top-level @scheme[require] of module-level definitions. A top-level @racket[require]
@tech{instantiates} a module at @tech{phase} 0, if the module is not @tech{instantiates} a module at @tech{phase} 0, if the module is not
already @tech{instantiate}d at phase 0. A top-level already @tech{instantiate}d at phase 0. A top-level
@scheme[(require (for-syntax ....))] @tech{instantiates} a module at @racket[(require (for-syntax ....))] @tech{instantiates} a module at
@tech{phase} 1 (if it is not already @tech{instantiate}d at that @tech{phase} 1 (if it is not already @tech{instantiate}d at that
level); @scheme[for-syntax] also has a different binding level); @racket[for-syntax] also has a different binding
effect on further program parsing, as described in effect on further program parsing, as described in
@secref["intro-binding"]. @secref["intro-binding"].
Within a module, some definitions are shifted by a phase already; the Within a module, some definitions are shifted by a phase already; the
@scheme[define-for-syntax] form is like @scheme[define], but it @racket[define-for-syntax] form is like @racket[define], but it
defines a variable at relative @tech{phase} 1, instead of relative defines a variable at relative @tech{phase} 1, instead of relative
@tech{phase} 0. Thus, if the module is @tech{instantiate}d at phase 1, @tech{phase} 0. Thus, if the module is @tech{instantiate}d at phase 1,
the variables for @scheme[define-for-syntax] are created at phase 2, the variables for @racket[define-for-syntax] are created at phase 2,
and so on. Moreover, this relative phase acts as another layer of and so on. Moreover, this relative phase acts as another layer of
prefixing, so that a @scheme[define] of @scheme[x] and a prefixing, so that a @racket[define] of @racket[x] and a
@scheme[define-for-syntax] of @scheme[x] can co-exist in a module @racket[define-for-syntax] of @racket[x] can co-exist in a module
without colliding. Again, the higher phases are mainly related to without colliding. Again, the higher phases are mainly related to
program parsing, instead of normal evaluation. program parsing, instead of normal evaluation.
If a module @tech{instantiate}d at @tech{phase} @math{n} If a module @tech{instantiate}d at @tech{phase} @math{n}
@scheme[require]s another module, then the @scheme[require]d module is @racket[require]s another module, then the @racket[require]d module is
first @tech{instantiate}d at phase @math{n}, and so on first @tech{instantiate}d at phase @math{n}, and so on
transitively. (Module @scheme[require]s cannot form cycles.) If a transitively. (Module @racket[require]s cannot form cycles.) If a
module @tech{instantiate}d at phase @math{n} @scheme[require]s module @tech{instantiate}d at phase @math{n} @racket[require]s
@scheme[for-syntax] another module, the other module becomes @racket[for-syntax] another module, the other module becomes
@deftech{available} at @tech{phase} @math{n+1}, and it may later be @deftech{available} at @tech{phase} @math{n+1}, and it may later be
@tech{instantiate}d at @tech{phase} @math{n+1}. If a module that is @tech{instantiate}d at @tech{phase} @math{n+1}. If a module that is
@tech{available} at phase @math{n} for @math{n>0} @scheme[require]s @tech{available} at phase @math{n} for @math{n>0} @racket[require]s
@scheme[for-template] another module, the other module becomes @racket[for-template] another module, the other module becomes
@tech{available} at @tech{phase} @math{n-1}, and so @tech{available} at @tech{phase} @math{n-1}, and so
on. @tech{Instantiation}s of @tech{available} modules above on. @tech{Instantiation}s of @tech{available} modules above
@tech{phase} 0 are triggered on demand as described in @tech{phase} 0 are triggered on demand as described in
@ -591,11 +591,11 @@ module forms (see @secref["mod-parse"]), and are, again, conceptually
distinguished by prefixes. distinguished by prefixes.
Top-level variables can exist in multiple phases in the same way as Top-level variables can exist in multiple phases in the same way as
within modules. For example, @scheme[define-for-syntax] creates a within modules. For example, @racket[define-for-syntax] creates a
@tech{phase} 1 variable. Furthermore, reflective operations like @tech{phase} 1 variable. Furthermore, reflective operations like
@scheme[make-base-namespace] and @scheme[eval] provide access to @racket[make-base-namespace] and @racket[eval] provide access to
top-level variables in higher @tech{phases}, while module top-level variables in higher @tech{phases}, while module
@tech{instantiations} (triggered by with @scheme[require]) relative to such @tech{instantiations} (triggered by with @racket[require]) relative to such
top-levels are in corresponding higher @tech{phase}s. top-levels are in corresponding higher @tech{phase}s.
@;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -620,9 +620,9 @@ re-declared, each re-declaration of the module is immediately
@margin-note/ref{See @secref["contmarks"] for continuation-mark forms and functions.} @margin-note/ref{See @secref["contmarks"] for continuation-mark forms and functions.}
Every continuation @scheme[_C] can be partitioned into Every continuation @racket[_C] can be partitioned into
@deftech{continuation frames} @frame[1], @frame[2], ..., @frame["n"] @deftech{continuation frames} @frame[1], @frame[2], ..., @frame["n"]
such that @scheme[_C] = @*sub[@frame[1] @*sub[@frame[2] @*sub["..." such that @racket[_C] = @*sub[@frame[1] @*sub[@frame[2] @*sub["..."
@frame["n"]]]], and no frame @frame["i"] can be itself partitioned @frame["n"]]]], and no frame @frame["i"] can be itself partitioned
into smaller continuations. Evaluation steps add and remove frames to into smaller continuations. Evaluation steps add and remove frames to
the current continuation, typically one at a time. the current continuation, typically one at a time.
@ -675,13 +675,13 @@ escape-continuation aborts can cross continuation barriers.
@margin-note/ref{See @secref["concurrency"] for thread and synchronization functions.} @margin-note/ref{See @secref["concurrency"] for thread and synchronization functions.}
Scheme supports multiple @deftech{threads} of evaluation. Threads run Racket supports multiple @deftech{threads} of evaluation. Threads run
concurrently, in the sense that one thread can preempt another without concurrently, in the sense that one thread can preempt another without
its cooperation, but threads currently all run on the same processor its cooperation, but threads currently all run on the same processor
(i.e., the same underlying OS process and thread). See also (i.e., the same underlying OS process and thread). See also
@secref["futures"]. @secref["futures"].
Threads are created explicitly by functions such as @scheme[thread]. Threads are created explicitly by functions such as @racket[thread].
In terms of the evaluation model, each step in evaluation actually consists of multiple concurrent In terms of the evaluation model, each step in evaluation actually consists of multiple concurrent
expressions, up to one per thread, rather than a single expression. The expressions all expressions, up to one per thread, rather than a single expression. The expressions all
share the same objects and top-level variables, so that they can share the same objects and top-level variables, so that they can
@ -705,7 +705,7 @@ is created) as all other threads.
@margin-note/ref{See @secref["parameters"] for parameter forms and functions.} @margin-note/ref{See @secref["parameters"] for parameter forms and functions.}
@deftech{Parameters} are essentially a derived concept in Scheme; they @deftech{Parameters} are essentially a derived concept in Racket; they
are defined in terms of @tech{continuation marks} and @tech{thread are defined in terms of @tech{continuation marks} and @tech{thread
cells}. However, parameters are also built in, in the sense that some cells}. However, parameters are also built in, in the sense that some
primitive procedures consult parameter values. For example, the primitive procedures consult parameter values. For example, the
@ -726,8 +726,8 @@ preserved thread cell, and the combination of thread cell and current
thread yields the parameter's value. A parameter procedure sets or thread yields the parameter's value. A parameter procedure sets or
accesses the relevant thread cell for its parameter. accesses the relevant thread cell for its parameter.
Various operations, such as @scheme[parameterize] or Various operations, such as @racket[parameterize] or
@scheme[call-with-parameterization], install a parameterization into @racket[call-with-parameterization], install a parameterization into
the current continuation's frame. the current continuation's frame.
@;------------------------------------------------------------------------ @;------------------------------------------------------------------------
@ -735,7 +735,7 @@ the current continuation's frame.
@margin-note/ref{See @secref["exns"] for exception forms, functions, and types.} @margin-note/ref{See @secref["exns"] for exception forms, functions, and types.}
@deftech{Exceptions} are essentially a derived concept in Scheme; they @deftech{Exceptions} are essentially a derived concept in Racket; they
are defined in terms of continuations, prompts, and continuation are defined in terms of continuations, prompts, and continuation
marks. However, exceptions are also built in, in the sense that marks. However, exceptions are also built in, in the sense that
primitive forms and procedures may raise exceptions. primitive forms and procedures may raise exceptions.
@ -763,7 +763,7 @@ A @deftech{custodian} manages a collection of threads,
@tech{file-stream ports}, TCP ports, @tech{TCP listeners}, @tech{UDP @tech{file-stream ports}, TCP ports, @tech{TCP listeners}, @tech{UDP
sockets}, and @tech{byte converters}. Whenever a thread, etc. is sockets}, and @tech{byte converters}. Whenever a thread, etc. is
created, it is placed under the management of the @deftech{current created, it is placed under the management of the @deftech{current
custodian} as determined by the @scheme[current-custodian] custodian} as determined by the @racket[current-custodian]
@tech{parameter}. @tech{parameter}.
@margin-note{In MrEd, custodians also manage eventspaces.} @margin-note{In MrEd, custodians also manage eventspaces.}
@ -774,20 +774,20 @@ Every object managed by a subordinate custodian is also managed by the
custodian's owner. custodian's owner.
When a @tech{custodian} is shut down via When a @tech{custodian} is shut down via
@scheme[custodian-shutdown-all], it forcibly and immediately closes @racket[custodian-shutdown-all], it forcibly and immediately closes
the ports, TCP connections, etc. that it manages, as well as the ports, TCP connections, etc. that it manages, as well as
terminating (or suspending) its threads. A custodian that has been terminating (or suspending) its threads. A custodian that has been
shut down cannot manage new objects. If the current custodian is shut shut down cannot manage new objects. If the current custodian is shut
down before a procedure is called to create a managed resource (e.g., down before a procedure is called to create a managed resource (e.g.,
@scheme[open-input-port], @scheme[thread]), the @racket[open-input-port], @racket[thread]), the
@exnraise[exn:fail:contract]. @exnraise[exn:fail:contract].
A thread can have multiple managing custodians, and a suspended thread A thread can have multiple managing custodians, and a suspended thread
created with @scheme[thread/suspend-to-kill] can have zero created with @racket[thread/suspend-to-kill] can have zero
custodians. Extra custodians become associated with a thread through custodians. Extra custodians become associated with a thread through
@scheme[thread-resume] (see @secref["threadkill"]). When a thread @racket[thread-resume] (see @secref["threadkill"]). When a thread
has multiple custodians, it is not necessarily killed by a has multiple custodians, it is not necessarily killed by a
@scheme[custodian-shutdown-all], but shut-down custodians are removed @racket[custodian-shutdown-all], but shut-down custodians are removed
from the thread's managing set, and the thread is killed when its from the thread's managing set, and the thread is killed when its
managing set becomes empty. managing set becomes empty.
@ -800,15 +800,15 @@ collected, at which point its subordinates become immediately
subordinate to the collected custodian's superordinate custodian. subordinate to the collected custodian's superordinate custodian.
In addition to the other entities managed by a custodian, a In addition to the other entities managed by a custodian, a
@deftech{custodian box} created with @scheme[make-custodian-box] @deftech{custodian box} created with @racket[make-custodian-box]
strongly holds onto a value placed in the box until the box's strongly holds onto a value placed in the box until the box's
custodian is shut down. The custodian only weakly retains the box custodian is shut down. The custodian only weakly retains the box
itself, however (so the box and its content can be collected if there itself, however (so the box and its content can be collected if there
are no other references to them). are no other references to them).
When PLT Scheme is compiled with support for per-custodian memory When Racket is compiled with support for per-custodian memory
accounting (see @scheme[custodian-memory-accounting-available?]), the accounting (see @racket[custodian-memory-accounting-available?]), the
@scheme[current-memory-use] procedure can report a custodian-specific @racket[current-memory-use] procedure can report a custodian-specific
result. This result determines how much memory is occupied by objects result. This result determines how much memory is occupied by objects
that are reachable from the custodian's managed values, especially its that are reachable from the custodian's managed values, especially its
threads, and including its sub-custodians' managed values. If an threads, and including its sub-custodians' managed values. If an

View File

@ -89,12 +89,14 @@ expression is a list of the results in order.
@deftogether[( @deftogether[(
@defform[(for/hash (for-clause ...) body ...+)] @defform[(for/hash (for-clause ...) body ...+)]
@defform[(for/hasheq (for-clause ...) body ...+)] @defform[(for/hasheq (for-clause ...) body ...+)]
@defform[(for/hasheqv (for-clause ...) body ...+)]
)]{ )]{
Like @scheme[for/list], but the result is an immutable @tech{hash Like @scheme[for/list], but the result is an immutable @tech{hash
table}; @scheme[for/hash] creates a table using @scheme[equal?] to table}; @scheme[for/hash] creates a table using @scheme[equal?] to
distinguish keys, and @scheme[for/hasheq] produces a table using distinguish keys, @scheme[for/hasheq] produces a table using
@scheme[eq?]. The last expression in the @scheme[body]s must return @scheme[eq?], and @scheme[for/hasheqv] produces a table using
@scheme[eqv?]. The last expression in the @scheme[body]s must return
two values: a key and a value to extend the hash table accumulated by two values: a key and a value to extend the hash table accumulated by
the iteration. the iteration.
@ -212,6 +214,7 @@ nested.
@defform[(for*/lists (id ...) (for-clause ...) body ...+)] @defform[(for*/lists (id ...) (for-clause ...) body ...+)]
@defform[(for*/hash (for-clause ...) body ...+)] @defform[(for*/hash (for-clause ...) body ...+)]
@defform[(for*/hasheq (for-clause ...) body ...+)] @defform[(for*/hasheq (for-clause ...) body ...+)]
@defform[(for*/hasheqv (for-clause ...) body ...+)]
@defform[(for*/and (for-clause ...) body ...+)] @defform[(for*/and (for-clause ...) body ...+)]
@defform[(for*/or (for-clause ...) body ...+)] @defform[(for*/or (for-clause ...) body ...+)]
@defform[(for*/first (for-clause ...) body ...+)] @defform[(for*/first (for-clause ...) body ...+)]

View File

@ -86,6 +86,11 @@ unpredictable.
Returns @scheme[#t] if @scheme[v] is a @tech{hash table}, @scheme[#f] Returns @scheme[#t] if @scheme[v] is a @tech{hash table}, @scheme[#f]
otherwise.} otherwise.}
@defproc[(hash-equal? [hash hash?]) boolean?]{
Returns @scheme[#t] if @scheme[hash] compares keys with @scheme[equal?],
@scheme[#f] if it compares with @scheme[eq?] or @scheme[eqv?].}
@defproc[(hash-eqv? [hash hash?]) boolean?]{ @defproc[(hash-eqv? [hash hash?]) boolean?]{
Returns @scheme[#t] if @scheme[hash] compares keys with @scheme[eqv?], Returns @scheme[#t] if @scheme[hash] compares keys with @scheme[eqv?],
@ -102,73 +107,69 @@ Returns @scheme[#t] if @scheme[hash] compares keys with @scheme[eq?],
Returns @scheme[#t] if @scheme[hash] retains its keys weakly, Returns @scheme[#t] if @scheme[hash] retains its keys weakly,
@scheme[#f] if it retains keys strongly.} @scheme[#f] if it retains keys strongly.}
@deftogether[(
@defproc[(hash [key any/c] [val any/c] ... ...) (and/c hash? hash-equal? immutable?)]
@defproc[(hasheq [key any/c] [val any/c] ... ...) (and/c hash? hash-eq? immutable?)]
@defproc[(hasheqv [key any/c] [val any/c] ... ...) (and/c hash? hash-eqv? immutable?)]
)]{
@defproc[(make-hash [assocs (listof pair?) null]) hash?]{ Creates an immutable hash table with each given @scheme[key] mapped to
the following @scheme[val]; each @scheme[key] must have a @scheme[val],
so the total number of arguments to @scheme[hash] must be even.
Creates a mutable hash table that holds keys strongly and that uses The @scheme[hash] procedure creates a table where keys are compared
@scheme[equal?] to compare keys. See also @scheme[make-custom-hash]. with @scheme[equal?], @scheme[hasheq] procedure creates a table where
keys are compared with @scheme[eq?], and @scheme[hasheqv] procedure
creates a table where keys are compared with @scheme[eqv?].
The @scheme[key] to @scheme[val] mappings are added to the table in
the order that they appear in the argument list, so later mappings can
hide earlier mappings if the @scheme[key]s are equal.}
@deftogether[(
@defproc[(make-hash [assocs (listof pair?) null]) (and/c hash? hash-equal?)]
@defproc[(make-hasheqv [assocs (listof pair?) null]) (and/c hash? hash-eqv?)]
@defproc[(make-hasheq [assocs (listof pair?) null]) (and/c hash? hash-eq?)]
)]{
Creates a mutable hash table that holds keys strongly.
The @scheme[make-hash] procedure creates a table where keys are
compared with @scheme[equal?], @scheme[make-hasheq] procedure creates
a table where keys are compared with @scheme[eq?], and
@scheme[make-hasheqv] procedure creates a table where keys are
compared with @scheme[eqv?].
The table is initialized with the content of @scheme[assocs]. In each The table is initialized with the content of @scheme[assocs]. In each
element of @scheme[assocs], the @scheme[car] is a key, and the element of @scheme[assocs], the @scheme[car] is a key, and the
@scheme[cdr] is the corresponding value. The mappings are added to the @scheme[cdr] is the corresponding value. The mappings are added to the
table in the order that they appear in @scheme[assocs], so later table in the order that they appear in @scheme[assocs], so later
mappings can hide earlier mappings.} mappings can hide earlier mappings.
See also @scheme[make-custom-hash].}
@defproc[(make-hasheqv [assocs (listof pair?) null]) (and/c hash? hash-eqv?)]{ @deftogether[(
@defproc[(make-weak-hash [assocs (listof pair?) null]) (and/c hash? hash-equal? hash-weak?)]
Creates a mutable hash table that holds keys strongly and that @defproc[(make-weak-hasheqv [assocs (listof pair?) null]) (and/c hash? hash-eqv? hash-weak?)]
uses @scheme[eqv?] to compare keys. The table is initialized with the @defproc[(make-weak-hasheq [assocs (listof pair?) null]) (and/c hash? hash-eq? hash-weak?)]
content of @scheme[assocs] as in @scheme[make-hash].} )]{
@defproc[(make-hasheq [assocs (listof pair?) null]) (and/c hash? hash-eq?)]{
Creates a mutable hash table that holds keys strongly and that
uses @scheme[eq?] to compare keys. The table is initialized with the
content of @scheme[assocs] as in @scheme[make-hash].}
@defproc[(make-weak-hash [assocs (listof pair?) null]) (and/c hash? hash-weak?)]{
Creates a mutable hash table that holds keys weakly and that
uses @scheme[equal?] to compare keys; see also
@scheme[make-weak-custom-hash]. The table is initialized with the
content of @scheme[assocs] as in @scheme[make-hash].}
@defproc[(make-weak-hasheqv [assocs (listof pair?) null]) (and/c hash? hash-eqv? hash-weak?)]{
Creates a mutable hash table that holds keys weakly and that
uses @scheme[eqv?] to compare keys. The table is initialized with the
content of @scheme[assocs] as in @scheme[make-hash].}
@defproc[(make-weak-hasheq [assocs (listof pair?) null]) (and/c hash? hash-eq? hash-weak?)]{
Creates a mutable hash table that holds keys weakly and that
uses @scheme[eq?] to compare keys. The table is initialized with the
content of @scheme[assocs] as in @scheme[make-hash].}
Like @scheme[make-hash], @scheme[make-hasheq], and
@scheme[make-hasheqv], but creates a mutable hash table that holds
keys weakly.}
@deftogether[(
@defproc[(make-immutable-hash [assocs (listof pair?)]) @defproc[(make-immutable-hash [assocs (listof pair?)])
(and/c hash? immutable?)]{ (and/c hash? hash-equal? immutable?)]
Creates an immutable hash table that compares keys with
@scheme[equal?]. The table is created with the content of
@scheme[assocs] as in @scheme[make-hash].}
@defproc[(make-immutable-hasheqv [assocs (listof pair?)]) @defproc[(make-immutable-hasheqv [assocs (listof pair?)])
(and/c hash? hash-eqv? immutable?)]{ (and/c hash? hash-eqv? immutable?)]
Like @scheme[make-immutable-hash], but the resulting hash table
compares keys with @scheme[eqv?].}
@defproc[(make-immutable-hasheq [assocs (listof pair?)]) @defproc[(make-immutable-hasheq [assocs (listof pair?)])
(and/c hash? hash-eq? immutable?)]{ (and/c hash? hash-eq? immutable?)]
)]{
Like @scheme[make-immutable-hash], but the resulting hash table Like @scheme[hash], @scheme[hasheq], and @scheme[hasheqv], but accepts
compares keys with @scheme[eq?].} the key--value mapping in association-list form like
@scheme[make-hash], @scheme[make-hasheq], and @scheme[make-hasheqv].}
@defproc[(hash-set! [hash (and/c hash? (not/c immutable?))] @defproc[(hash-set! [hash (and/c hash? (not/c immutable?))]

View File

@ -43,7 +43,7 @@
(define (*prog-steps cont? objs defs progs) (define (*prog-steps cont? objs defs progs)
(make-table (make-table
'((valignment top top top top top top)) '((valignment baseline baseline baseline baseline baseline baseline))
(apply (apply
append append
(for/list ([obj (or objs (in-naturals))] (for/list ([obj (or objs (in-naturals))]

View File

@ -109,6 +109,7 @@ Applies the procedure @scheme[proc] to each element in
@scheme[set] in an unspecified order, accumulating the results @scheme[set] in an unspecified order, accumulating the results
into a list.} into a list.}
@defproc[(set-for-each [set set?] @defproc[(set-for-each [set set?]
[proc (any/c . -> . any)]) [proc (any/c . -> . any)])
void?]{ void?]{
@ -116,7 +117,21 @@ into a list.}
Applies @scheme[proc] to each element in @scheme[set] (for the Applies @scheme[proc] to each element in @scheme[set] (for the
side-effects of @scheme[proc]) in an unspecified order.} side-effects of @scheme[proc]) in an unspecified order.}
@defproc[(in-set [set set?]) sequence?]{ @defproc[(in-set [set set?]) sequence?]{
Explicitly converts a set to a sequence for use with @scheme[for] and Explicitly converts a set to a sequence for use with @scheme[for] and
other forms.} other forms.}
@deftogether[(
@defform[(for/set (for-clause ...) body ...+)]
@defform[(for/seteq (for-clause ...) body ...+)]
@defform[(for/seteqv (for-clause ...) body ...+)]
@defform[(for*/set (for-clause ...) body ...+)]
@defform[(for*/seteq (for-clause ...) body ...+)]
@defform[(for*/seteqv (for-clause ...) body ...+)]
)]{
Analogous to @scheme[for/list] and @scheme[for*/list], but to
construct a set instead of a list.}

View File

@ -3,13 +3,13 @@
(for-syntax mzscheme) (for-syntax mzscheme)
"mz.ss") "mz.ss")
@(define scheme-eval (make-base-eval)) @(define racket-eval (make-base-eval))
@(interaction-eval #:eval scheme-eval (require (for-syntax racket/base))) @(interaction-eval #:eval racket-eval (require (for-syntax racket/base)))
@;------------------------------------------------------------------------ @;------------------------------------------------------------------------
@title[#:tag "syntax-model"]{Syntax Model} @title[#:tag "syntax-model"]{Syntax Model}
The syntax of a Scheme program is defined by The syntax of a Racket program is defined by
@itemize[ @itemize[
@ -22,7 +22,7 @@ The syntax of a Scheme program is defined by
] ]
For details on the @tech{read} phase, see @secref["reader"]. Source For details on the @tech{read} phase, see @secref["reader"]. Source
code is normally read in @scheme[read-syntax] mode, which produces a code is normally read in @racket[read-syntax] mode, which produces a
@tech{syntax object}. @tech{syntax object}.
The @tech{expand} phase recursively processes a @tech{syntax object} The @tech{expand} phase recursively processes a @tech{syntax object}
@ -38,7 +38,7 @@ new binding information.
@guideintro["binding"]{binding} @guideintro["binding"]{binding}
An @deftech{identifier} is source-program entity. Parsing (i.e., An @deftech{identifier} is source-program entity. Parsing (i.e.,
expanding) a Scheme program reveals that some @tech{identifiers} expanding) a Racket program reveals that some @tech{identifiers}
correspond to @tech{variables}, some refer to syntactic forms, and correspond to @tech{variables}, some refer to syntactic forms, and
some are quoted to produce a symbol or a syntax object. some are quoted to produce a symbol or a syntax object.
@ -55,13 +55,13 @@ uses of an @tech{identifier} refer to the @tech{shadowing}
For example, as a bit of source, the text For example, as a bit of source, the text
@schemeblock[(let ([x 5]) x)] @racketblock[(let ([x 5]) x)]
includes two @tech{identifiers}: @scheme[let] and @scheme[x] (which includes two @tech{identifiers}: @racket[let] and @racket[x] (which
appears twice). When this source is parsed in a typical appears twice). When this source is parsed in a typical
@tech{environment}, @scheme[x] turns out to represent a @tech{environment}, @racket[x] turns out to represent a
@tech{variable} (unlike @scheme[let]). In particular, the first @tech{variable} (unlike @racket[let]). In particular, the first
@scheme[x] @tech{binds} the second @scheme[x]. @racket[x] @tech{binds} the second @racket[x].
A @deftech{top-level binding} is a @tech{binding} from a definition at A @deftech{top-level binding} is a @tech{binding} from a definition at
the top-level; a @deftech{module binding} is a binding from a the top-level; a @deftech{module binding} is a binding from a
@ -73,10 +73,10 @@ identifiers are called @tech{unbound} in a module context.
Throughout the documentation, @tech{identifiers} are typeset to Throughout the documentation, @tech{identifiers} are typeset to
suggest the way that they are parsed. A black, boldface suggest the way that they are parsed. A black, boldface
@tech{identifier} like @scheme[lambda] indicates as a reference to a @tech{identifier} like @racket[lambda] indicates as a reference to a
syntactic form. A plain blue @tech{identifier} like @schemeidfont{x} syntactic form. A plain blue @tech{identifier} like @racketidfont{x}
is a @tech{variable} or a reference to an unspecified @tech{top-level is a @tech{variable} or a reference to an unspecified @tech{top-level
variable}. A hyperlinked @tech{identifier} @scheme[cons] is a variable}. A hyperlinked @tech{identifier} @racket[cons] is a
reference to a specific @tech{top-level variable}. reference to a specific @tech{top-level variable}.
Every binding has a @deftech{phase level} in which it can be Every binding has a @deftech{phase level} in which it can be
@ -108,17 +108,17 @@ different phase levels.
@;------------------------------------------------------------------------ @;------------------------------------------------------------------------
@section[#:tag "stxobj-model"]{Syntax Objects} @section[#:tag "stxobj-model"]{Syntax Objects}
A @deftech{syntax object} combines a simpler Scheme value, such as a A @deftech{syntax object} combines a simpler Racket value, such as a
symbol or pair, with @deftech{lexical information} about bindings, symbol or pair, with @deftech{lexical information} about bindings,
source-location information, @tech{syntax properties}, and source-location information, @tech{syntax properties}, and
@tech{syntax certificates}. In particular, an @tech{identifier} is @tech{syntax certificates}. In particular, an @tech{identifier} is
represented as a symbol object that combines a symbol and lexical and represented as a symbol object that combines a symbol and lexical and
other information. other information.
For example, a @schemeidfont{car} @tech{identifier} might have For example, a @racketidfont{car} @tech{identifier} might have
@tech{lexical information} that designates it as the @scheme[car] from @tech{lexical information} that designates it as the @racket[car] from
the @schememodname[racket/base] language (i.e., the built-in the @racketmodname[racket/base] language (i.e., the built-in
@scheme[car]). Similarly, a @schemeidfont{lambda} identifier's @racket[car]). Similarly, a @racketidfont{lambda} identifier's
@tech{lexical information} may indicate that it represents a procedure @tech{lexical information} may indicate that it represents a procedure
form. Some other @tech{identifier}'s @tech{lexical information} may form. Some other @tech{identifier}'s @tech{lexical information} may
indicate that it references a @tech{top-level variable}. indicate that it references a @tech{top-level variable}.
@ -128,42 +128,42 @@ an @tech{identifier} or simple constant, its internal components can
be extracted. Even for extracted identifier, detailed information be extracted. Even for extracted identifier, detailed information
about binding is available mostly indirectly; two identifiers can be about binding is available mostly indirectly; two identifiers can be
compared to see if they refer to the same binding (i.e., compared to see if they refer to the same binding (i.e.,
@scheme[free-identifier=?]), or whether each identifier would bind the @racket[free-identifier=?]), or whether each identifier would bind the
other if one was in a binding position and the other in an expression other if one was in a binding position and the other in an expression
position (i.e., @scheme[bound-identifier=?]). position (i.e., @racket[bound-identifier=?]).
For example, the when the program written as For example, the when the program written as
@schemeblock[(let ([x 5]) (+ x 6))] @racketblock[(let ([x 5]) (+ x 6))]
is represented as a @tech{syntax object}, then two @tech{syntax is represented as a @tech{syntax object}, then two @tech{syntax
objects} can be extracted for the two @scheme[x]s. Both the objects} can be extracted for the two @racket[x]s. Both the
@scheme[free-identifier=?] and @scheme[bound-identifier=?] predicates @racket[free-identifier=?] and @racket[bound-identifier=?] predicates
will indicate that the @scheme[x]s are the same. In contrast, the will indicate that the @racket[x]s are the same. In contrast, the
@scheme[let] @tech{identifier} is not @scheme[free-identifier=?] or @racket[let] @tech{identifier} is not @racket[free-identifier=?] or
@scheme[bound-identifier=?] to either @scheme[x]. @racket[bound-identifier=?] to either @racket[x].
The @tech{lexical information} in a @tech{syntax object} is The @tech{lexical information} in a @tech{syntax object} is
independent of the other half, and it can be copied to a new syntax independent of the other half, and it can be copied to a new syntax
object in combination with an arbitrary other Scheme value. Thus, object in combination with an arbitrary other Racket value. Thus,
identifier-@tech{binding} information in a @tech{syntax object} is identifier-@tech{binding} information in a @tech{syntax object} is
predicated on the symbolic name of the @tech{identifier} as well as predicated on the symbolic name of the @tech{identifier} as well as
the identifier's @tech{lexical information}; the same question with the identifier's @tech{lexical information}; the same question with
the same @tech{lexical information} but different base value can the same @tech{lexical information} but different base value can
produce a different answer. produce a different answer.
For example, combining the lexical information from @scheme[let] in For example, combining the lexical information from @racket[let] in
the program above to @scheme['x] would not produce an identifier that the program above to @racket['x] would not produce an identifier that
is @scheme[free-identifier=?] to either @scheme[x], since it does not is @racket[free-identifier=?] to either @racket[x], since it does not
appear in the scope of the @scheme[x] binding. Combining the lexical appear in the scope of the @racket[x] binding. Combining the lexical
context of the @scheme[6] with @scheme['x], in contrast, would produce context of the @racket[6] with @racket['x], in contrast, would produce
an identifier that is @scheme[bound-identifier=?] to both @scheme[x]s. an identifier that is @racket[bound-identifier=?] to both @racket[x]s.
The @scheme[quote-syntax] form bridges the evaluation of a program and The @racket[quote-syntax] form bridges the evaluation of a program and
the representation of a program. Specifically, @scheme[(quote-syntax the representation of a program. Specifically, @racket[(quote-syntax
_datum)] produces a syntax object that preserves all of the lexical _datum)] produces a syntax object that preserves all of the lexical
information that @scheme[_datum] had when it was parsed as part of the information that @racket[_datum] had when it was parsed as part of the
@scheme[quote-syntax] form. @racket[quote-syntax] form.
@;------------------------------------------------------------------------ @;------------------------------------------------------------------------
@section[#:tag "expansion"]{Expansion@aux-elem{ (Parsing)}} @section[#:tag "expansion"]{Expansion@aux-elem{ (Parsing)}}
@ -184,7 +184,7 @@ following grammar:
@margin-note{Beware that the symbolic names of identifiers in a fully @margin-note{Beware that the symbolic names of identifiers in a fully
expanded program may not match the symbolic names in the grammar. Only expanded program may not match the symbolic names in the grammar. Only
the binding (according to @scheme[free-identifier=?]) matters.} the binding (according to @racket[free-identifier=?]) matters.}
@schemegrammar*[ @schemegrammar*[
#:literals (#%expression module #%plain-module-begin begin #%provide #:literals (#%expression module #%plain-module-begin begin #%provide
@ -217,7 +217,7 @@ the binding (according to @scheme[free-identifier=?]) matters.}
(letrec-values (((id ...) expr) ...) (letrec-values (((id ...) expr) ...)
expr ...+) expr ...+)
(set! id expr) (set! id expr)
(@#,scheme[quote] datum) (@#,racket[quote] datum)
(quote-syntax datum) (quote-syntax datum)
(with-continuation-mark expr expr expr) (with-continuation-mark expr expr expr)
(#%plain-app expr ...+) (#%plain-app expr ...+)
@ -235,29 +235,29 @@ information} on its @tech{identifiers} indicates the
@tech{parse}. @tech{parse}.
More specifically, the typesetting of identifiers in the above grammar More specifically, the typesetting of identifiers in the above grammar
is significant. For example, the second case for @scheme[_expr] is a is significant. For example, the second case for @racket[_expr] is a
@tech{syntax-object} list whose first element is an @tech{identifier}, @tech{syntax-object} list whose first element is an @tech{identifier},
where the @tech{identifier}'s @tech{lexical information} specifies a where the @tech{identifier}'s @tech{lexical information} specifies a
binding to the @scheme[#%plain-lambda] of the binding to the @racket[#%plain-lambda] of the
@schememodname[racket/base] language (i.e., the @tech{identifier} is @racketmodname[racket/base] language (i.e., the @tech{identifier} is
@scheme[free-identifier=?] to one whose binding is @racket[free-identifier=?] to one whose binding is
@scheme[#%plain-lambda]). In all cases, identifiers above typeset as @racket[#%plain-lambda]). In all cases, identifiers above typeset as
syntactic-form names refer to the bindings defined in syntactic-form names refer to the bindings defined in
@secref["syntax"]. @secref["syntax"].
Only @tech{phase levels} 0 and 1 are relevant for the parse of a Only @tech{phase levels} 0 and 1 are relevant for the parse of a
program (though the @scheme[_datum] in a @scheme[quote-syntax] form program (though the @racket[_datum] in a @racket[quote-syntax] form
preserves its information for all @tech{phase level}s). In particular, preserves its information for all @tech{phase level}s). In particular,
the relevant @tech{phase level} is 0, except for the @scheme[_expr]s the relevant @tech{phase level} is 0, except for the @racket[_expr]s
in a @scheme[define-syntax], @scheme[define-syntaxes], in a @racket[define-syntax], @racket[define-syntaxes],
@scheme[define-for-syntax], or @scheme[define-values-for-syntax] form, @racket[define-for-syntax], or @racket[define-values-for-syntax] form,
in which case the relevant @tech{phase level} is 1 (for which in which case the relevant @tech{phase level} is 1 (for which
comparisons are made using @scheme[free-transformer-identifier=?] comparisons are made using @racket[free-transformer-identifier=?]
instead of @scheme[free-identifier=?]). instead of @racket[free-identifier=?]).
In addition to the grammar above, @scheme[letrec-syntaxes+values] can In addition to the grammar above, @racket[letrec-syntaxes+values] can
appear in a fully local-expanded expression, such as the result from appear in a fully local-expanded expression, such as the result from
@scheme[local-expand] when the stop list is empty. @racket[local-expand] when the stop list is empty.
@;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@subsection[#:tag "expand-steps"]{Expansion Steps} @subsection[#:tag "expand-steps"]{Expansion Steps}
@ -274,15 +274,15 @@ the @tech{syntax object} being expanded:
@tech{binding} other than as a @tech{top-level variable}, that @tech{binding} other than as a @tech{top-level variable}, that
@tech{binding} is used to continue. If the @tech{identifier} @tech{binding} is used to continue. If the @tech{identifier}
has no @tech{binding}, a new @tech{syntax-object} symbol has no @tech{binding}, a new @tech{syntax-object} symbol
@scheme['#%top] is created using the @tech{lexical information} @racket['#%top] is created using the @tech{lexical information}
of the @tech{identifier}; if this @schemeidfont{#%top} of the @tech{identifier}; if this @racketidfont{#%top}
@tech{identifier} has no @tech{binding} (other than as a @tech{identifier} has no @tech{binding} (other than as a
@tech{top-level variable}), then parsing fails with an @tech{top-level variable}), then parsing fails with an
@scheme[exn:fail:syntax] exception. Otherwise, the new @racket[exn:fail:syntax] exception. Otherwise, the new
@tech{identifier} is combined with the original @tech{identifier} is combined with the original
@tech{identifier} in a new @tech{syntax-object} pair (also @tech{identifier} in a new @tech{syntax-object} pair (also
using the same @tech{lexical information} as the original using the same @tech{lexical information} as the original
@tech{identifier}), and the @schemeidfont{#%top} @tech{binding} @tech{identifier}), and the @racketidfont{#%top} @tech{binding}
is used to continue.} is used to continue.}
@item{If it is a @tech{syntax-object} pair whose first element is an @item{If it is a @tech{syntax-object} pair whose first element is an
@ -291,26 +291,26 @@ the @tech{syntax object} being expanded:
the @tech{identifier}'s @tech{binding} is used to continue.} the @tech{identifier}'s @tech{binding} is used to continue.}
@item{If it is a @tech{syntax-object} pair of any other form, then a @item{If it is a @tech{syntax-object} pair of any other form, then a
new @tech{syntax-object} symbol @scheme['#%app] is created new @tech{syntax-object} symbol @racket['#%app] is created
using the @tech{lexical information} of the pair. If the using the @tech{lexical information} of the pair. If the
resulting @schemeidfont{#%app} @tech{identifier} has no resulting @racketidfont{#%app} @tech{identifier} has no
binding, parsing fails with an @scheme[exn:fail:syntax] binding, parsing fails with an @racket[exn:fail:syntax]
exception. Otherwise, the new @tech{identifier} is combined exception. Otherwise, the new @tech{identifier} is combined
with the original pair to form a new @tech{syntax-object} pair with the original pair to form a new @tech{syntax-object} pair
(also using the same @tech{lexical information} as the original (also using the same @tech{lexical information} as the original
pair), and the @schemeidfont{#%app} @tech{binding} is used to pair), and the @racketidfont{#%app} @tech{binding} is used to
continue.} continue.}
@item{If it is any other syntax object, then a new @item{If it is any other syntax object, then a new
@tech{syntax-object} symbol @scheme['#%datum] is created using @tech{syntax-object} symbol @racket['#%datum] is created using
the @tech{lexical information} of the original @tech{syntax the @tech{lexical information} of the original @tech{syntax
object}. If the resulting @schemeidfont{#%datum} object}. If the resulting @racketidfont{#%datum}
@tech{identifier} has no @tech{binding}, parsing fails with an @tech{identifier} has no @tech{binding}, parsing fails with an
@scheme[exn:fail:syntax] exception. Otherwise, the new @racket[exn:fail:syntax] exception. Otherwise, the new
@tech{identifier} is combined with the original @tech{syntax @tech{identifier} is combined with the original @tech{syntax
object} in a new @tech{syntax-object} pair (using the same object} in a new @tech{syntax-object} pair (using the same
@tech{lexical information} as the original pair), and the @tech{lexical information} as the original pair), and the
@schemeidfont{#%datum} @tech{binding} is used to continue.} @racketidfont{#%datum} @tech{binding} is used to continue.}
] ]
@ -321,24 +321,24 @@ things:
@itemize[ @itemize[
@item{A @tech{transformer binding}, such as introduced by @item{A @tech{transformer binding}, such as introduced by
@scheme[define-syntax] or @scheme[let-syntax]. If the @racket[define-syntax] or @racket[let-syntax]. If the
associated value is a procedure of one argument, the procedure associated value is a procedure of one argument, the procedure
is called as a @tech{syntax transformer} (described below), and is called as a @tech{syntax transformer} (described below), and
parsing starts again with the @tech{syntax-object} result. If parsing starts again with the @tech{syntax-object} result. If
the @tech{transformer binding} is to any other kind of value, the @tech{transformer binding} is to any other kind of value,
parsing fails with an @scheme[exn:fail:syntax] exception. The parsing fails with an @racket[exn:fail:syntax] exception. The
call to the @tech{syntax transformer} is @scheme[parameterize]d call to the @tech{syntax transformer} is @racket[parameterize]d
to set @scheme[current-namespace] to a @tech{namespace} that to set @racket[current-namespace] to a @tech{namespace} that
shares @tech{bindings} and @tech{variables} with the namespace shares @tech{bindings} and @tech{variables} with the namespace
being used to expand, except that its @tech{base phase} is one being used to expand, except that its @tech{base phase} is one
greater.} greater.}
@item{A @tech{variable} @tech{binding}, such as introduced by a @item{A @tech{variable} @tech{binding}, such as introduced by a
module-level @scheme[define] or by @scheme[let]. In this case, module-level @racket[define] or by @racket[let]. In this case,
if the form being parsed is just an @tech{identifier}, then it if the form being parsed is just an @tech{identifier}, then it
is parsed as a reference to the corresponding is parsed as a reference to the corresponding
@tech{variable}. If the form being parsed is a @tech{variable}. If the form being parsed is a
@tech{syntax-object} pair, then an @scheme[#%app] is added to @tech{syntax-object} pair, then an @racket[#%app] is added to
the front of the @tech{syntax-object} pair in the same way as the front of the @tech{syntax-object} pair in the same way as
when the first item in the @tech{syntax-object} pair is not an when the first item in the @tech{syntax-object} pair is not an
identifier (third case in the previous enumeration), and identifier (third case in the previous enumeration), and
@ -357,7 +357,7 @@ things:
Each expansion step occurs in a particular @deftech{context}, and Each expansion step occurs in a particular @deftech{context}, and
transformers and core syntactic forms may expand differently for transformers and core syntactic forms may expand differently for
different @tech{contexts}. For example, a @scheme[module] form is different @tech{contexts}. For example, a @racket[module] form is
allowed only in a @tech{top-level context}, and it fails in other allowed only in a @tech{top-level context}, and it fails in other
contexts. The possible @tech{contexts} are as follows: contexts. The possible @tech{contexts} are as follows:
@ -365,7 +365,7 @@ contexts. The possible @tech{contexts} are as follows:
@item{@deftech{top-level context} : outside of any module, definition, or @item{@deftech{top-level context} : outside of any module, definition, or
expression, except that sub-expressions of a top-level expression, except that sub-expressions of a top-level
@scheme[begin] form are also expanded as top-level forms.} @racket[begin] form are also expanded as top-level forms.}
@item{@deftech{module-begin context} : inside the body of a module, as the @item{@deftech{module-begin context} : inside the body of a module, as the
only form within the module.} only form within the module.}
@ -382,7 +382,7 @@ contexts. The possible @tech{contexts} are as follows:
] ]
Different core @tech{syntactic forms} parse sub-forms using different Different core @tech{syntactic forms} parse sub-forms using different
@tech{contexts}. For example, a @scheme[let] form always parses the @tech{contexts}. For example, a @racket[let] form always parses the
right-hand expressions of a binding in an @tech{expression context}, right-hand expressions of a binding in an @tech{expression context},
but it starts parsing the body in an @tech{internal-definition but it starts parsing the body in an @tech{internal-definition
context}. context}.
@ -395,58 +395,58 @@ core syntactic forms are encountered:
@itemize[ @itemize[
@item{When a @scheme[require] form is encountered at the top level or @item{When a @racket[require] form is encountered at the top level or
module level, all lexical information derived from the top module level, all lexical information derived from the top
level or the specific module's level are extended with bindings level or the specific module's level are extended with bindings
from the specified modules. If not otherwise indicated in the from the specified modules. If not otherwise indicated in the
@scheme[require] form, bindings are introduced at the @racket[require] form, bindings are introduced at the
@tech{phase level}s specified by the exporting modules: @tech{phase level}s specified by the exporting modules:
@tech{phase level} 0 for each normal @scheme[provide], @tech{phase level} 0 for each normal @racket[provide],
@tech{phase level} 1 for each @scheme[for-syntax] @tech{phase level} 1 for each @racket[for-syntax]
@scheme[provide], and so on. The @scheme[for-meta] @racket[provide], and so on. The @racket[for-meta]
@scheme[provide] form allows exports at an arbitrary @racket[provide] form allows exports at an arbitrary
@tech{phase level} (as long as a binding exists within the @tech{phase level} (as long as a binding exists within the
module at the @tech{phase level}). module at the @tech{phase level}).
A @scheme[for-syntax] sub-form within @scheme[require] imports A @racket[for-syntax] sub-form within @racket[require] imports
similarly, but the resulting bindings have a @tech{phase level} similarly, but the resulting bindings have a @tech{phase level}
that is one more than the exported @tech{phase levels}, when that is one more than the exported @tech{phase levels}, when
exports for the @tech{label phase level} are still imported at exports for the @tech{label phase level} are still imported at
the @tech{label phase level}. More generally, a the @tech{label phase level}. More generally, a
@scheme[for-meta] sub-form within @scheme[require] imports with @racket[for-meta] sub-form within @racket[require] imports with
the specified @tech{phase level} shift; if the specified shift the specified @tech{phase level} shift; if the specified shift
is @scheme[#f], or if @scheme[for-label] is used to import, is @racket[#f], or if @racket[for-label] is used to import,
then all bindings are imported into the @tech{label phase then all bindings are imported into the @tech{label phase
level}.} level}.}
@item{When a @scheme[define], @scheme[define-values], @item{When a @racket[define], @racket[define-values],
@scheme[define-syntax], or @scheme[define-syntaxes] form is @racket[define-syntax], or @racket[define-syntaxes] form is
encountered at the top level or module level, all lexical encountered at the top level or module level, all lexical
information derived from the top level or the specific module's information derived from the top level or the specific module's
level is extended with bindings for the specified identifiers level is extended with bindings for the specified identifiers
at @tech{phase level} 0 (i.e., the @tech{base environment} is at @tech{phase level} 0 (i.e., the @tech{base environment} is
extended).} extended).}
@item{When a @scheme[define-for-syntax] or @item{When a @racket[define-for-syntax] or
@scheme[define-values-for-syntax] form is encountered at the @racket[define-values-for-syntax] form is encountered at the
top level or module level, bindings are introduced as for top level or module level, bindings are introduced as for
@scheme[define-values], but at @tech{phase level} 1 (i.e., the @racket[define-values], but at @tech{phase level} 1 (i.e., the
@tech{transformer environment} is extended).} @tech{transformer environment} is extended).}
@item{When a @scheme[let-values] form is encountered, the body of the @item{When a @racket[let-values] form is encountered, the body of the
@scheme[let-values] form is extended (by creating new @racket[let-values] form is extended (by creating new
@tech{syntax objects}) with bindings for the specified @tech{syntax objects}) with bindings for the specified
identifiers. The same bindings are added to the identifiers identifiers. The same bindings are added to the identifiers
themselves, so that the identifiers in binding position are themselves, so that the identifiers in binding position are
@scheme[bound-identifier=?] to uses in the fully expanded form, @racket[bound-identifier=?] to uses in the fully expanded form,
and so they are not @scheme[bound-identifier=?] to other and so they are not @racket[bound-identifier=?] to other
identifiers. The bindings are available for use at the identifiers. The bindings are available for use at the
@tech{phase level} at which the @scheme[let-values] form is @tech{phase level} at which the @racket[let-values] form is
expanded.} expanded.}
@item{When a @scheme[letrec-values] or @item{When a @racket[letrec-values] or
@scheme[letrec-syntaxes+values] form is encountered, bindings @racket[letrec-syntaxes+values] form is encountered, bindings
are added as for @scheme[let-values], except that the are added as for @racket[let-values], except that the
right-hand-side expressions are also extended with the right-hand-side expressions are also extended with the
bindings.} bindings.}
@ -457,26 +457,26 @@ core syntactic forms are encountered:
A new binding in lexical information maps to a new variable. The A new binding in lexical information maps to a new variable. The
identifiers mapped to this variable are those that currently have the identifiers mapped to this variable are those that currently have the
same binding (i.e., that are currently @scheme[bound-identifier=?]) to same binding (i.e., that are currently @racket[bound-identifier=?]) to
the identifier associated with the binding. the identifier associated with the binding.
For example, in For example, in
@schemeblock[ @racketblock[
(let-values ([(x) 10]) (+ x y)) (let-values ([(x) 10]) (+ x y))
] ]
the binding introduced for @scheme[x] applies to the @scheme[x] in the the binding introduced for @racket[x] applies to the @racket[x] in the
body, but not the @scheme[y] n the body, because (at the point in body, but not the @racket[y] n the body, because (at the point in
expansion where the @scheme[let-values] form is encountered) the expansion where the @racket[let-values] form is encountered) the
binding @scheme[x] and the body @scheme[y] are not binding @racket[x] and the body @racket[y] are not
@scheme[bound-identifier=?]. @racket[bound-identifier=?].
@;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@subsection[#:tag "transformer-model"]{Transformer Bindings} @subsection[#:tag "transformer-model"]{Transformer Bindings}
In a @tech{top-level context} or @tech{module context}, when the In a @tech{top-level context} or @tech{module context}, when the
expander encounters a @scheme[define-syntaxes] form, the binding that expander encounters a @racket[define-syntaxes] form, the binding that
it introduces for the defined identifiers is a @deftech{transformer it introduces for the defined identifiers is a @deftech{transformer
binding}. The @tech{value} of the @tech{binding} exists at expansion binding}. The @tech{value} of the @tech{binding} exists at expansion
time, rather than run time (though the two times can overlap), though time, rather than run time (though the two times can overlap), though
@ -484,13 +484,13 @@ the binding itself is introduced with @tech{phase level} 0 (i.e., in
the @tech{base environment}). the @tech{base environment}).
The @tech{value} for the binding is obtained by evaluating the The @tech{value} for the binding is obtained by evaluating the
expression in the @scheme[define-syntaxes] form. This expression must expression in the @racket[define-syntaxes] form. This expression must
be @tech{expand}ed (i.e. parsed) before it can be evaluated, and it is be @tech{expand}ed (i.e. parsed) before it can be evaluated, and it is
expanded at @tech{phase level} 1 (i.e., in the @tech{transformer expanded at @tech{phase level} 1 (i.e., in the @tech{transformer
environment}) instead of @tech{phase level} 0. environment}) instead of @tech{phase level} 0.
If the resulting @scheme[value] is a procedure of one argument or If the resulting @racket[value] is a procedure of one argument or
the result of @scheme[make-set!-transformer] on a procedure, then it the result of @racket[make-set!-transformer] on a procedure, then it
is used as a @deftech{syntax transformer} (a.k.a. @deftech{macro}). is used as a @deftech{syntax transformer} (a.k.a. @deftech{macro}).
The procedure is expected to accept a syntax object and return a The procedure is expected to accept a syntax object and return a
syntax object. A use of the binding (at @tech{phase level} 0) triggers syntax object. A use of the binding (at @tech{phase level} 0) triggers
@ -503,7 +503,7 @@ applies to all sub-@tech{syntax objects}). The result of the
transformer is similarly extended with the same @tech{syntax transformer is similarly extended with the same @tech{syntax
mark}. When a @tech{syntax object}'s @tech{lexical information} mark}. When a @tech{syntax object}'s @tech{lexical information}
includes the same mark twice in a row, the marks effectively includes the same mark twice in a row, the marks effectively
cancel. Otherwise, two identifiers are @scheme[bound-identifier=?] cancel. Otherwise, two identifiers are @racket[bound-identifier=?]
(that is, one can bind the other) only if they have the same binding (that is, one can bind the other) only if they have the same binding
and if they have the same marks---counting only marks that were added and if they have the same marks---counting only marks that were added
after the binding. after the binding.
@ -512,7 +512,7 @@ This marking process helps keep binding in an expanded program
consistent with the lexical structure of the source program. For consistent with the lexical structure of the source program. For
example, the expanded form of the program example, the expanded form of the program
@schemeblock[ @racketblock[
(define x 12) (define x 12)
(define-syntax m (define-syntax m
(syntax-rules () (syntax-rules ()
@ -522,7 +522,7 @@ example, the expanded form of the program
is is
@schemeblock[ @racketblock[
(define x 12) (define x 12)
(define-syntax m (define-syntax m
(syntax-rules () (syntax-rules ()
@ -530,42 +530,42 @@ is
(let-values ([(x) 10]) x) (let-values ([(x) 10]) x)
] ]
However, the result of the last expression is @scheme[12], not However, the result of the last expression is @racket[12], not
@scheme[10]. The reason is that the transformer bound to @scheme[m] @racket[10]. The reason is that the transformer bound to @racket[m]
introduces the binding @scheme[x], but the referencing @scheme[x] is introduces the binding @racket[x], but the referencing @racket[x] is
present in the argument to the transformer. The introduced @scheme[x] present in the argument to the transformer. The introduced @racket[x]
is the one left with a mark, and the reference @scheme[x] has no mark, is the one left with a mark, and the reference @racket[x] has no mark,
so the binding @scheme[x] is not @scheme[bound-identifier=?] to the so the binding @racket[x] is not @racket[bound-identifier=?] to the
body @scheme[x]. body @racket[x].
The @scheme[set!] form works with the @scheme[make-set!-transformer] The @racket[set!] form works with the @racket[make-set!-transformer]
and @scheme[prop:set!-transformer] property to support and @racket[prop:set!-transformer] property to support
@deftech{assignment transformers} that transform @scheme[set!] @deftech{assignment transformers} that transform @racket[set!]
expressions. An @tech{assignment transformer} contains a procedure expressions. An @tech{assignment transformer} contains a procedure
that is applied by @scheme[set!] in the same way as a normal that is applied by @racket[set!] in the same way as a normal
transformer by the expander. transformer by the expander.
The @scheme[make-rename-transformer] procedure or The @racket[make-rename-transformer] procedure or
@scheme[prop:rename-transformer] property creates a value that is also @racket[prop:rename-transformer] property creates a value that is also
handled specially by the expander and by @scheme[set!] as a handled specially by the expander and by @racket[set!] as a
transformer binding's value. When @scheme[_id] is bound to a transformer binding's value. When @racket[_id] is bound to a
@deftech{rename transformer} produced by @deftech{rename transformer} produced by
@scheme[make-rename-transformer], it is replaced with the target @racket[make-rename-transformer], it is replaced with the target
identifier passed to @scheme[make-rename-transformer]. In addition, as identifier passed to @racket[make-rename-transformer]. In addition, as
long as the target identifier does not have a true value for the long as the target identifier does not have a true value for the
@scheme['not-free-identifier=?] @tech{syntax property}, the lexical information that @racket['not-free-identifier=?] @tech{syntax property}, the lexical information that
contains the binding of @scheme[_id] is also enriched so that contains the binding of @racket[_id] is also enriched so that
@scheme[_id] is @scheme[free-identifier=?] to the target identifier, @racket[_id] is @racket[free-identifier=?] to the target identifier,
@scheme[identifier-binding] returns the same results for both @racket[identifier-binding] returns the same results for both
identifiers, and @scheme[provide] exports @scheme[_id] as the target identifiers, and @racket[provide] exports @racket[_id] as the target
identifier. Finally, the binding is treated specially by identifier. Finally, the binding is treated specially by
@scheme[syntax-local-value], and @racket[syntax-local-value], and
@scheme[syntax-local-make-delta-introducer] as used by @tech{syntax @racket[syntax-local-make-delta-introducer] as used by @tech{syntax
transformer}s. transformer}s.
In addition to using marks to track introduced identifiers, the In addition to using marks to track introduced identifiers, the
expander tracks the expansion history of a form through @tech{syntax expander tracks the expansion history of a form through @tech{syntax
properties} such as @scheme['origin]. See @secref["stxprops"] for properties} such as @racket['origin]. See @secref["stxprops"] for
more information. more information.
Finally, the expander uses @tech{syntax certificates} to control the Finally, the expander uses @tech{syntax certificates} to control the
@ -573,15 +573,15 @@ way that unexported and protected @tech{module bindings} are used. See
@secref["stxcerts"] for more information on @tech{syntax @secref["stxcerts"] for more information on @tech{syntax
certificates}. certificates}.
The expander's handling of @scheme[letrec-values+syntaxes] is similar The expander's handling of @racket[letrec-values+syntaxes] is similar
to its handling of @scheme[define-syntaxes]. A to its handling of @racket[define-syntaxes]. A
@scheme[letrec-values+syntaxes] mist be expanded in an arbitrary phase @racket[letrec-values+syntaxes] mist be expanded in an arbitrary phase
level @math{n} (not just 0), in which case the expression for the level @math{n} (not just 0), in which case the expression for the
@tech{transformer binding} is expanded at @tech{phase level} @math{n+1}. @tech{transformer binding} is expanded at @tech{phase level} @math{n+1}.
The expression in a @scheme[define-for-syntax] or The expression in a @racket[define-for-syntax] or
@scheme[define-values-for-syntax] form is expanded and evaluated in @racket[define-values-for-syntax] form is expanded and evaluated in
the same way as for @scheme[syntax]. However, the introduced binding the same way as for @racket[syntax]. However, the introduced binding
is a variable binding at @tech{phase level} 1 (not a @tech{transformer is a variable binding at @tech{phase level} 1 (not a @tech{transformer
binding} at @tech{phase level} 0). binding} at @tech{phase level} 0).
@ -595,9 +595,9 @@ forms. Partial expansion works by cutting off the normal recursion
expansion when the relevant binding is for a primitive syntactic form. expansion when the relevant binding is for a primitive syntactic form.
As a special case, when expansion would otherwise add an As a special case, when expansion would otherwise add an
@schemeidfont{#%app}, @schemeidfont{#%datum}, or @schemeidfont{#%top} @racketidfont{#%app}, @racketidfont{#%datum}, or @racketidfont{#%top}
identifier to an expression, and when the binding turns out to be the identifier to an expression, and when the binding turns out to be the
primitive @scheme[#%app], @scheme[#%datum], or @scheme[#%top] form, primitive @racket[#%app], @racket[#%datum], or @racket[#%top] form,
then expansion stops without adding the identifier. then expansion stops without adding the identifier.
@;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -611,72 +611,72 @@ recursively expands only until the form becomes one of the following:
@itemize[ @itemize[
@item{A @scheme[define-values] or @scheme[define-syntaxes] form, for @item{A @racket[define-values] or @racket[define-syntaxes] form, for
any form other than the last one: The definition form is not any form other than the last one: The definition form is not
expanded further. Instead, the next form is expanded partially, expanded further. Instead, the next form is expanded partially,
and so on. As soon as an expression form is found, the and so on. As soon as an expression form is found, the
accumulated definition forms are converted to a accumulated definition forms are converted to a
@scheme[letrec-values] (if no @scheme[define-syntaxes] forms @racket[letrec-values] (if no @racket[define-syntaxes] forms
were found) or @scheme[letrec-syntaxes+values] form, moving the were found) or @racket[letrec-syntaxes+values] form, moving the
expression forms to the body to be expanded in expression expression forms to the body to be expanded in expression
context. context.
When a @scheme[define-values] form is discovered, the lexical When a @racket[define-values] form is discovered, the lexical
context of all syntax objects for the body sequence is context of all syntax objects for the body sequence is
immediately enriched with bindings for the immediately enriched with bindings for the
@scheme[define-values] form before expansion continues. When a @racket[define-values] form before expansion continues. When a
@scheme[define-syntaxes] form is discovered, the right-hand @racket[define-syntaxes] form is discovered, the right-hand
side is expanded and evaluated (as for a side is expanded and evaluated (as for a
@scheme[letrec-values+syntaxes] form), and a transformer @racket[letrec-values+syntaxes] form), and a transformer
binding is installed for the body sequence before expansion binding is installed for the body sequence before expansion
continues.} continues.}
@item{A primitive expression form other than @scheme[begin]: The @item{A primitive expression form other than @racket[begin]: The
expression is expanded in an expression context, along with all expression is expanded in an expression context, along with all
remaining body forms. If any definitions were found, this remaining body forms. If any definitions were found, this
expansion takes place after conversion to a expansion takes place after conversion to a
@scheme[letrec-values] or @scheme[letrec-syntaxes+values] @racket[letrec-values] or @racket[letrec-syntaxes+values]
form. Otherwise, the expressions are expanded immediately.} form. Otherwise, the expressions are expanded immediately.}
@item{A @scheme[begin] form: The sub-forms of the @scheme[begin] are @item{A @racket[begin] form: The sub-forms of the @racket[begin] are
spliced into the internal-definition sequence, and partial spliced into the internal-definition sequence, and partial
expansion continues with the first of the newly-spliced forms expansion continues with the first of the newly-spliced forms
(or the next form, if the @scheme[begin] had no sub-forms).} (or the next form, if the @racket[begin] had no sub-forms).}
] ]
If the last expression form turns out to be a @scheme[define-values] If the last expression form turns out to be a @racket[define-values]
or @scheme[define-syntaxes] form, expansion fails with a syntax error. or @racket[define-syntaxes] form, expansion fails with a syntax error.
@;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@subsection[#:tag "mod-parse"]{Module Phases and Visits} @subsection[#:tag "mod-parse"]{Module Phases and Visits}
A @scheme[require] form not only introduces @tech{bindings} at A @racket[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
it is encountered by the expander. That is, the expander it is encountered by the expander. That is, the expander
instantiates any @scheme[define-for-syntax]ed variables defined instantiates any @racket[define-for-syntax]ed variables defined
in the module, and also evaluates all expressions for in the module, and also evaluates all expressions for
@scheme[define-syntaxes] @tech{transformer bindings}. @racket[define-syntaxes] @tech{transformer bindings}.
Module @tech{visits} propagate through @scheme[require]s in the same Module @tech{visits} propagate through @racket[require]s in the same
way as module @tech{instantiation}. Moreover, when a module is way as module @tech{instantiation}. Moreover, when a module is
@tech{visit}ed at @tech{phase} 0, any module that it @scheme[require]s @tech{visit}ed at @tech{phase} 0, any module that it @racket[require]s
@scheme[for-syntax] is @tech{instantiate}d at @tech{phase} 1, while @racket[for-syntax] is @tech{instantiate}d at @tech{phase} 1, while
further @scheme[require]s @scheme[for-template] leading back further @racket[require]s @racket[for-template] leading back
to @tech{phase} 0 causes the required module to be visited at to @tech{phase} 0 causes the required module to be visited at
@tech{phase} 0 (i.e., not @tech{instantiate}d). @tech{phase} 0 (i.e., not @tech{instantiate}d).
During compilation, the top-level of module context is itself During compilation, the top-level of module context is itself
implicitly @tech{visit}ed. Thus, when the expander encounters implicitly @tech{visit}ed. Thus, when the expander encounters
@scheme[(require (for-syntax ....))], it immediately @racket[(require (for-syntax ....))], it immediately
@tech{instantiate}s the required module at @tech{phase} 1, in addition @tech{instantiate}s the required module at @tech{phase} 1, in addition
to adding bindings at @tech{phase level} 1 (i.e., the to adding bindings at @tech{phase level} 1 (i.e., the
@tech{transformer environment}). Similarly, the expander immediately @tech{transformer environment}). Similarly, the expander immediately
evaluates any @scheme[define-values-for-syntax] form that it evaluates any @racket[define-values-for-syntax] form that it
encounters. encounters.
@tech{Phases} beyond 0 are @tech{visit}ed on demand. For example, @tech{Phases} beyond 0 are @tech{visit}ed on demand. For example,
when the right-hand side of a @tech{phase}-0 @scheme[let-syntax] is to when the right-hand side of a @tech{phase}-0 @racket[let-syntax] is to
be expanded, then modules that are @tech{available} at @tech{phase} 1 be expanded, then modules that are @tech{available} at @tech{phase} 1
are visited. More generally, initiating expansion at @tech{phase} are visited. More generally, initiating expansion at @tech{phase}
@math{n} @tech{visit}s modules at @tech{phase} @math{n}, which in turn @math{n} @tech{visit}s modules at @tech{phase} @math{n}, which in turn
@ -686,14 +686,14 @@ modules in the enclosing @tech{namespace}'s @tech{module registry};
a per-registry lock prevents multiple threads from concurrently a per-registry lock prevents multiple threads from concurrently
instantiating and visiting available modules. instantiating and visiting available modules.
When the expander encounters @scheme[require] and @scheme[(require When the expander encounters @racket[require] and @racket[(require
(for-syntax ....))] within a @tech{module context}, the resulting (for-syntax ....))] within a @tech{module context}, the resulting
@tech{visits} and @tech{instantiations} are specific to the expansion @tech{visits} and @tech{instantiations} are specific to the expansion
of the enclosing module, and are kept separate from @tech{visits} and of the enclosing module, and are kept separate from @tech{visits} and
@tech{instantiations} triggered from a @tech{top-level context} or @tech{instantiations} triggered from a @tech{top-level context} or
from the expansion of a different module. Along the same lines, when a from the expansion of a different module. Along the same lines, when a
module is attached to a namespace through module is attached to a namespace through
@scheme[namespace-attach-module], modules that it @scheme[require]s @racket[namespace-attach-module], modules that it @racket[require]s
are transitively attached, but instances are attached only at are transitively attached, but instances are attached only at
phases at or below the namespace's @tech{base phase}. phases at or below the namespace's @tech{base phase}.
@ -710,7 +710,7 @@ When a top-level definition binds an identifier that originates from a
(define-syntax def-and-use-of-x (define-syntax def-and-use-of-x
(syntax-rules () (syntax-rules ()
[(def-and-use-of-x val) [(def-and-use-of-x val)
(code:comment @#,t{@scheme[x] below originates from this macro:}) (code:comment @#,t{@racket[x] below originates from this macro:})
(begin (define x val) x)])) (begin (define x val) x)]))
(define x 1) (define x 1)
x x
@ -720,7 +720,7 @@ x
(define-syntax def-and-use (define-syntax def-and-use
(syntax-rules () (syntax-rules ()
[(def-and-use x val) [(def-and-use x val)
(code:comment @#,t{@scheme{x} below was provided by the macro use:}) (code:comment @#,t{@racket{x} below was provided by the macro use:})
(begin (define x val) x)])) (begin (define x val) x)]))
(def-and-use x 3) (def-and-use x 3)
x x
@ -733,12 +733,12 @@ For a top-level definition (outside of a module), the order of
definition were not present. (No such dependency on order occurs definition were not present. (No such dependency on order occurs
within a module, since a module binding covers the entire module within a module, since a module binding covers the entire module
body.) To support the declaration of an identifier before its use, body.) To support the declaration of an identifier before its use,
the @scheme[define-syntaxes] form avoids binding an identifier if the the @racket[define-syntaxes] form avoids binding an identifier if the
body of the @scheme[define-syntaxes] declaration produces zero body of the @racket[define-syntaxes] declaration produces zero
results. results.
@examples[ @examples[
#:eval scheme-eval #:eval racket-eval
(define bucket-1 0) (define bucket-1 0)
(define bucket-2 0) (define bucket-2 0)
(define-syntax def-and-set!-use-of-x (define-syntax def-and-set!-use-of-x
@ -755,7 +755,7 @@ bucket-2
(syntax-rules () (syntax-rules ()
[(def-and-use) [(def-and-use)
(begin (begin
(code:comment @#,t{Initial reference to @scheme[even] precedes definition:}) (code:comment @#,t{Initial reference to @racket[even] precedes definition:})
(define (odd x) (if (zero? x) #f (even (sub1 x)))) (define (odd x) (if (zero? x) #f (even (sub1 x))))
(define (even x) (if (zero? x) #t (odd (sub1 x)))) (define (even x) (if (zero? x) #t (odd (sub1 x))))
(odd 17))])) (odd 17))]))
@ -765,7 +765,7 @@ bucket-2
(syntax-rules () (syntax-rules ()
[(def-and-use) [(def-and-use)
(begin (begin
(code:comment @#,t{Declare before definition via no-values @scheme[define-syntaxes]:}) (code:comment @#,t{Declare before definition via no-values @racket[define-syntaxes]:})
(define-syntaxes (odd even) (values)) (define-syntaxes (odd even) (values))
(define (odd x) (if (zero? x) #f (even (sub1 x)))) (define (odd x) (if (zero? x) #f (even (sub1 x))))
(define (even x) (if (zero? x) #t (odd (sub1 x)))) (define (even x) (if (zero? x) #t (odd (sub1 x))))
@ -773,29 +773,29 @@ bucket-2
(defs-and-uses) (defs-and-uses)
] ]
Macro-generated @scheme{require} and @scheme{provide} Macro-generated @racket{require} and @racket{provide}
clauses also introduce and reference generation-specific bindings: clauses also introduce and reference generation-specific bindings:
@itemize[ @itemize[
@item{In @scheme[require], for a @scheme[_require-spec] of the form @item{In @racket[require], for a @racket[_require-spec] of the form
@scheme[(rename-in [_orig-id _bind-id])] or @scheme[(only-in @racket[(rename-in [_orig-id _bind-id])] or @racket[(only-in
.... [_orig-id _bind-id])], the @scheme[_bind-id] is bound only for .... [_orig-id _bind-id])], the @racket[_bind-id] is bound only for
uses of the identifier generated by the same macro expansion as uses of the identifier generated by the same macro expansion as
@scheme[_bind-id]. In @scheme[require] for other @racket[_bind-id]. In @racket[require] for other
@scheme[_require-spec]s, the generator of the @scheme[_require-spec] @racket[_require-spec]s, the generator of the @racket[_require-spec]
determines the scope of the bindings.} determines the scope of the bindings.}
@item{In @scheme[provide], for a @scheme[_provide-spec] of the form @item{In @racket[provide], for a @racket[_provide-spec] of the form
@scheme[_id], the exported identifier is the one that binds @racket[_id], the exported identifier is the one that binds
@scheme[_id] within the module in a generator-specific way, but the @racket[_id] within the module in a generator-specific way, but the
external name is the plain @scheme[_id]. The exceptions for external name is the plain @racket[_id]. The exceptions for
@scheme[all-except-out] are similarly determined in a @racket[all-except-out] are similarly determined in a
generator-specific way, as is the @scheme[_orig-id] binding of a generator-specific way, as is the @racket[_orig-id] binding of a
@scheme[rename-out] form, but plain identifiers are used for the @racket[rename-out] form, but plain identifiers are used for the
external names. For @scheme[all-defined-out], only identifiers with external names. For @racket[all-defined-out], only identifiers with
definitions having the same generator as the definitions having the same generator as the
@scheme[(all-defined-out)] form are exported; the external name is @racket[(all-defined-out)] form are exported; the external name is
the plain identifier from the definition.} the plain identifier from the definition.}
] ]
@ -815,7 +815,7 @@ string, so it is suitable for saving and re-loading code.
Although individual read, expand, compile, and evaluate operations are Although individual read, expand, compile, and evaluate operations are
available, the operations are often combined automatically. For available, the operations are often combined automatically. For
example, the @scheme[eval] procedure takes a syntax object and expands example, the @racket[eval] procedure takes a syntax object and expands
it, compiles it, and evaluates it. it, compiles it, and evaluates it.
@;------------------------------------------------------------------------ @;------------------------------------------------------------------------
@ -826,7 +826,7 @@ manipulate namespaces.}
A @deftech{namespace} is a top-level mapping from symbols to binding A @deftech{namespace} is a top-level mapping from symbols to binding
information. It is the starting point for expanding an expression; a information. It is the starting point for expanding an expression; a
@tech{syntax object} produced by @scheme[read-syntax] has no initial @tech{syntax object} produced by @racket[read-syntax] has no initial
lexical context; the @tech{syntax object} can be expanded after lexical context; the @tech{syntax object} can be expanded after
initializing it with the mappings of a particular namespace. A initializing it with the mappings of a particular namespace. A
namespace is also the starting point evaluating expanded code, where namespace is also the starting point evaluating expanded code, where
@ -850,7 +850,7 @@ An ``empty'' namespace maps all symbols to top-level variables.
Certain evaluations extend a namespace for future expansions; Certain evaluations extend a namespace for future expansions;
importing a module into the top-level adjusts the namespace bindings importing a module into the top-level adjusts the namespace bindings
for all of the imported named, and evaluating a top-level for all of the imported named, and evaluating a top-level
@scheme[define] form updates the namespace's mapping to refer to a @racket[define] form updates the namespace's mapping to refer to a
variable (in addition to installing a value into the variable). variable (in addition to installing a value into the variable).
A namespace also has a @deftech{module registry} that maps module A namespace also has a @deftech{module registry} that maps module
@ -863,9 +863,9 @@ distinct set of module instances in each @tech{phase}. That is, even
though module declarations are shared for all @tech{phase levels}, though module declarations are shared for all @tech{phase levels},
module instances are distinct for each @tech{phase}. Each namespace module instances are distinct for each @tech{phase}. Each namespace
has a @deftech{base phase}, which corresponds to the phase used by has a @deftech{base phase}, which corresponds to the phase used by
reflective operations such as @scheme[eval] and reflective operations such as @racket[eval] and
@scheme[dynamic-require]. In particular, using @scheme[eval] on a @racket[dynamic-require]. In particular, using @racket[eval] on a
@scheme[require] form @tech{instantiates} a module in the namespace's @racket[require] form @tech{instantiates} a module in the namespace's
@tech{base phase}. @tech{base phase}.
After a namespace is created, module instances from existing After a namespace is created, module instances from existing
@ -890,14 +890,14 @@ and to start evaluating expanded/compiled code.
@examples[ @examples[
(code:line (code:line
(define x 'orig) (code:comment @#,t{define in the original namespace})) (define x 'orig) (code:comment @#,t{define in the original namespace}))
(code:comment @#,t{The following @scheme[let] expression is compiled in the original}) (code:comment @#,t{The following @racket[let] expression is compiled in the original})
(code:comment @#,t{namespace, so direct references to @scheme[x] see @scheme['orig].}) (code:comment @#,t{namespace, so direct references to @racket[x] see @racket['orig].})
(code:line (code:line
(let ([n (make-base-namespace)]) (code:comment @#,t{make new namespace}) (let ([n (make-base-namespace)]) (code:comment @#,t{make new namespace})
(parameterize ([current-namespace n]) (parameterize ([current-namespace n])
(eval '(define x 'new)) (code:comment @#,t{evals in the new namespace}) (eval '(define x 'new)) (code:comment @#,t{evals in the new namespace})
(display x) (code:comment @#,t{displays @scheme['orig]}) (display x) (code:comment @#,t{displays @racket['orig]})
(display (eval 'x)))) (code:comment @#,t{displays @scheme['new]})) (display (eval 'x)))) (code:comment @#,t{displays @racket['new]}))
] ]
A @tech{namespace} is purely a top-level entity, not to be confused A @tech{namespace} is purely a top-level entity, not to be confused
@ -924,7 +924,7 @@ x
(define x 7) (define x 7)
x x
(f) (f)
(module m mzscheme (define x 8) (provide x)) (module m racket (define x 8) (provide x))
(require 'm) (require 'm)
(eval:alts x (eval 'x)) (eval:alts x (eval 'x))
(f) (f)
@ -937,28 +937,28 @@ To improve error reporting, names are inferred at compile-time for
certain kinds of values, such as procedures. For example, evaluating certain kinds of values, such as procedures. For example, evaluating
the following expression: the following expression:
@schemeblock[ @racketblock[
(let ([f (lambda () 0)]) (f 1 2 3)) (let ([f (lambda () 0)]) (f 1 2 3))
] ]
produces an error message because too many arguments are provided to produces an error message because too many arguments are provided to
the procedure. The error message is able to report @schemeidfont{f} as the procedure. The error message is able to report @racketidfont{f} as
the name of the procedure. In this case, Scheme decides, at the name of the procedure. In this case, Racket decides, at
compile-time, to name as @scheme['f] all procedures created by the compile-time, to name as @racket['f] all procedures created by the
@scheme[let]-bound @scheme[lambda]. @racket[let]-bound @racket[lambda].
Names are inferred whenever possible for procedures. Names closer to Names are inferred whenever possible for procedures. Names closer to
an expression take precedence. For example, in an expression take precedence. For example, in
@schemeblock[ @racketblock[
(define my-f (define my-f
(let ([f (lambda () 0)]) f)) (let ([f (lambda () 0)]) f))
] ]
the procedure bound to @scheme[my-f] will have the inferred name the procedure bound to @racket[my-f] will have the inferred name
@scheme['f]. @racket['f].
When an @indexed-scheme['inferred-name] property is attached to a When an @indexed-racket['inferred-name] property is attached to a
syntax object for an expression (see @secref["stxprops"]), the syntax object for an expression (see @secref["stxprops"]), the
property value is used for naming the expression, and it overrides any property value is used for naming the expression, and it overrides any
name that was inferred from the expression's context. Normally, the name that was inferred from the expression's context. Normally, the
@ -967,8 +967,8 @@ property value should be a symbol or an identifier.
When an inferred name is not available, but a source location is When an inferred name is not available, but a source location is
available, a name is constructed using the source location available, a name is constructed using the source location
information. Inferred and property-assigned names are also available information. Inferred and property-assigned names are also available
to syntax transformers, via @scheme[syntax-local-name]. to syntax transformers, via @racket[syntax-local-name].
@;---------------------------------------- @;----------------------------------------
@close-eval[scheme-eval] @close-eval[racket-eval]

File diff suppressed because it is too large Load Diff

View File

@ -102,4 +102,8 @@
;; ---------------------------------------- ;; ----------------------------------------
(test (set 1 2 3) 'for/set (for/set ([i '(0 1 2)]) (add1 i)))
;; ----------------------------------------
(report-errs) (report-errs)

View File

@ -84,6 +84,7 @@
mzscheme/lang/reader mzscheme/lang/reader
scheme/base/lang/reader scheme/base/lang/reader
scheme/lang/reader scheme/lang/reader
scheme/private/lang/reader
scheme/private/provider/lang/reader scheme/private/provider/lang/reader
racket/base/lang/reader racket/base/lang/reader
racket/private/lang/reader racket/private/lang/reader

File diff suppressed because it is too large Load Diff

View File

@ -100,11 +100,15 @@ static Scheme_Object *make_weak_hasheqv(int argc, Scheme_Object *argv[]);
static Scheme_Object *make_immutable_hash(int argc, Scheme_Object *argv[]); static Scheme_Object *make_immutable_hash(int argc, Scheme_Object *argv[]);
static Scheme_Object *make_immutable_hasheq(int argc, Scheme_Object *argv[]); static Scheme_Object *make_immutable_hasheq(int argc, Scheme_Object *argv[]);
static Scheme_Object *make_immutable_hasheqv(int argc, Scheme_Object *argv[]); static Scheme_Object *make_immutable_hasheqv(int argc, Scheme_Object *argv[]);
static Scheme_Object *direct_hash(int argc, Scheme_Object *argv[]);
static Scheme_Object *direct_hasheq(int argc, Scheme_Object *argv[]);
static Scheme_Object *direct_hasheqv(int argc, Scheme_Object *argv[]);
static Scheme_Object *hash_table_count(int argc, Scheme_Object *argv[]); static Scheme_Object *hash_table_count(int argc, Scheme_Object *argv[]);
static Scheme_Object *hash_table_copy(int argc, Scheme_Object *argv[]); static Scheme_Object *hash_table_copy(int argc, Scheme_Object *argv[]);
static Scheme_Object *hash_p(int argc, Scheme_Object *argv[]); static Scheme_Object *hash_p(int argc, Scheme_Object *argv[]);
static Scheme_Object *hash_eq_p(int argc, Scheme_Object *argv[]); static Scheme_Object *hash_eq_p(int argc, Scheme_Object *argv[]);
static Scheme_Object *hash_eqv_p(int argc, Scheme_Object *argv[]); static Scheme_Object *hash_eqv_p(int argc, Scheme_Object *argv[]);
static Scheme_Object *hash_equal_p(int argc, Scheme_Object *argv[]);
static Scheme_Object *hash_weak_p(int argc, Scheme_Object *argv[]); static Scheme_Object *hash_weak_p(int argc, Scheme_Object *argv[]);
static Scheme_Object *hash_table_put_bang(int argc, Scheme_Object *argv[]); static Scheme_Object *hash_table_put_bang(int argc, Scheme_Object *argv[]);
static Scheme_Object *hash_table_put(int argc, Scheme_Object *argv[]); static Scheme_Object *hash_table_put(int argc, Scheme_Object *argv[]);
@ -511,6 +515,21 @@ scheme_init_list (Scheme_Env *env)
"make-immutable-hasheqv", "make-immutable-hasheqv",
1, 1), 1, 1),
env); env);
scheme_add_global_constant("hash",
scheme_make_immed_prim(direct_hash,
"hash",
0, -1),
env);
scheme_add_global_constant("hasheq",
scheme_make_immed_prim(direct_hasheq,
"hasheq",
0, -1),
env);
scheme_add_global_constant("hasheqv",
scheme_make_immed_prim(direct_hasheqv,
"hasheqv",
0, -1),
env);
scheme_add_global_constant("hash?", scheme_add_global_constant("hash?",
scheme_make_folding_prim(hash_p, scheme_make_folding_prim(hash_p,
"hash?", "hash?",
@ -526,6 +545,11 @@ scheme_init_list (Scheme_Env *env)
"hash-eqv?", "hash-eqv?",
1, 1, 1), 1, 1, 1),
env); env);
scheme_add_global_constant("hash-equal?",
scheme_make_folding_prim(hash_equal_p,
"hash-equal?",
1, 1, 1),
env);
scheme_add_global_constant("hash-weak?", scheme_add_global_constant("hash-weak?",
scheme_make_folding_prim(hash_weak_p, scheme_make_folding_prim(hash_weak_p,
"hash-weak?", "hash-weak?",
@ -1817,6 +1841,42 @@ static Scheme_Object *make_immutable_hasheqv(int argc, Scheme_Object *argv[])
return make_immutable_table("make-immutable-hasheqv", 2, argc, argv); return make_immutable_table("make-immutable-hasheqv", 2, argc, argv);
} }
static Scheme_Object *direct_table(const char *who, int kind, int argc, Scheme_Object *argv[])
{
int i;
Scheme_Hash_Tree *ht;
if (argc & 0x1) {
scheme_arg_mismatch(who,
"key does not have a value (i.e., an odd number of arguments were provided): ",
argv[argc-1]);
return NULL;
}
ht = scheme_make_hash_tree(kind);
for (i = 0; i < argc; i += 2) {
ht = scheme_hash_tree_set(ht, argv[i], argv[i+1]);
}
return (Scheme_Object *)ht;
}
static Scheme_Object *direct_hash(int argc, Scheme_Object *argv[])
{
return direct_table("hash", 1, argc, argv);
}
static Scheme_Object *direct_hasheq(int argc, Scheme_Object *argv[])
{
return direct_table("hasheq", 0, argc, argv);
}
static Scheme_Object *direct_hasheqv(int argc, Scheme_Object *argv[])
{
return direct_table("hasheqv", 2, argc, argv);
}
Scheme_Hash_Table *scheme_make_hash_table_equal() Scheme_Hash_Table *scheme_make_hash_table_equal()
{ {
Scheme_Hash_Table *t; Scheme_Hash_Table *t;
@ -2005,6 +2065,29 @@ static Scheme_Object *hash_eqv_p(int argc, Scheme_Object *argv[])
return scheme_false; return scheme_false;
} }
static Scheme_Object *hash_equal_p(int argc, Scheme_Object *argv[])
{
Scheme_Object *o = argv[0];
if (SCHEME_CHAPERONEP(o))
o = SCHEME_CHAPERONE_VAL(o);
if (SCHEME_HASHTP(o)) {
if (((Scheme_Hash_Table *)o)->compare == compare_equal)
return scheme_true;
} else if (SCHEME_HASHTRP(o)) {
if (SCHEME_HASHTR_FLAGS((Scheme_Hash_Tree *)o) & 0x1)
return scheme_true;
} else if (SCHEME_BUCKTP(o)) {
if (((Scheme_Bucket_Table *)o)->compare == compare_equal)
return scheme_true;
} else {
scheme_wrong_type("hash-equal?", "hash", 0, argc, argv);
}
return scheme_false;
}
static Scheme_Object *hash_weak_p(int argc, Scheme_Object *argv[]) static Scheme_Object *hash_weak_p(int argc, Scheme_Object *argv[])
{ {
Scheme_Object *o = argv[0]; Scheme_Object *o = argv[0];

View File

@ -13,7 +13,7 @@
#define USE_COMPILED_STARTUP 1 #define USE_COMPILED_STARTUP 1
#define EXPECTED_PRIM_COUNT 988 #define EXPECTED_PRIM_COUNT 992
#define EXPECTED_UNSAFE_COUNT 65 #define EXPECTED_UNSAFE_COUNT 65
#define EXPECTED_FLFXNUM_COUNT 53 #define EXPECTED_FLFXNUM_COUNT 53

View File

@ -13,12 +13,12 @@
consistently.) consistently.)
*/ */
#define MZSCHEME_VERSION "4.2.5.10" #define MZSCHEME_VERSION "4.2.5.11"
#define MZSCHEME_VERSION_X 4 #define MZSCHEME_VERSION_X 4
#define MZSCHEME_VERSION_Y 2 #define MZSCHEME_VERSION_Y 2
#define MZSCHEME_VERSION_Z 5 #define MZSCHEME_VERSION_Z 5
#define MZSCHEME_VERSION_W 10 #define MZSCHEME_VERSION_W 11
#define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y) #define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y)
#define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W) #define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W)