From fd7d8a412cd9d6c4cb8b4c2e43dabd65890267b8 Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Mon, 3 Dec 2012 17:24:38 -0500 Subject: [PATCH] move lazy-require to racket/lazy-require --- collects/db/main.rkt | 2 +- collects/db/private/generic/dsn.rkt | 2 +- collects/db/private/generic/place-server.rkt | 2 +- collects/openssl/mzssl.rkt | 2 +- collects/plot/plot2d/plot.rkt | 2 +- collects/plot/plot3d/plot.rkt | 2 +- collects/racket/lazy-require.rkt | 84 +++++++++++++++++++ collects/racket/match/define-forms.rkt | 2 +- collects/racket/match/match.rkt | 2 +- collects/racket/place.rkt | 2 +- collects/scribblings/reference/syntax.scrbl | 43 ++++++++++ .../syntax/parse/experimental/reflect.rkt | 2 +- .../syntax/parse/experimental/splicing.rkt | 2 +- collects/syntax/parse/private/litconv.rkt | 2 +- collects/syntax/parse/private/residual.rkt | 2 +- collects/syntax/parse/private/sc.rkt | 2 +- collects/typed-racket/base-env/prims.rkt | 2 +- collects/typed-racket/env/global-env.rkt | 2 +- collects/typed-racket/rep/free-variance.rkt | 2 +- collects/typed-racket/rep/rep-utils.rkt | 2 +- collects/typed-racket/rep/type-rep.rkt | 2 +- collects/typed-racket/types/abbrev.rkt | 2 +- collects/typed-racket/types/substitute.rkt | 2 +- collects/typed-racket/types/subtype.rkt | 2 +- collects/unstable/lazy-require.rkt | 82 +----------------- .../unstable/scribblings/lazy-require.scrbl | 36 -------- 26 files changed, 150 insertions(+), 139 deletions(-) create mode 100644 collects/racket/lazy-require.rkt diff --git a/collects/db/main.rkt b/collects/db/main.rkt index eaf701cd60..90a213c8dd 100644 --- a/collects/db/main.rkt +++ b/collects/db/main.rkt @@ -1,5 +1,5 @@ #lang racket/base -(require unstable/lazy-require +(require racket/lazy-require racket/contract/base "base.rkt") (provide (all-from-out "base.rkt")) diff --git a/collects/db/private/generic/dsn.rkt b/collects/db/private/generic/dsn.rkt index 31eeb6d1c9..fcd36878f6 100644 --- a/collects/db/private/generic/dsn.rkt +++ b/collects/db/private/generic/dsn.rkt @@ -1,5 +1,5 @@ #lang racket/base -(require unstable/lazy-require +(require racket/lazy-require syntax/parse/private/minimatch racket/file racket/list) diff --git a/collects/db/private/generic/place-server.rkt b/collects/db/private/generic/place-server.rkt index f27b2b0bc2..9219a9fab1 100644 --- a/collects/db/private/generic/place-server.rkt +++ b/collects/db/private/generic/place-server.rkt @@ -4,7 +4,7 @@ syntax/parse/private/minimatch racket/place racket/serialize - unstable/lazy-require + racket/lazy-require "interfaces.rkt" "prepared.rkt") (provide connection-server) diff --git a/collects/openssl/mzssl.rkt b/collects/openssl/mzssl.rkt index 13e7cb5fda..1d62f8c2f8 100644 --- a/collects/openssl/mzssl.rkt +++ b/collects/openssl/mzssl.rkt @@ -33,7 +33,7 @@ TO DO: racket/port racket/tcp racket/string - unstable/lazy-require + racket/lazy-require "libcrypto.rkt" "libssl.rkt") (lazy-require diff --git a/collects/plot/plot2d/plot.rkt b/collects/plot/plot2d/plot.rkt index 3c5b490245..439cb7c745 100644 --- a/collects/plot/plot2d/plot.rkt +++ b/collects/plot/plot2d/plot.rkt @@ -6,7 +6,7 @@ unstable/contract slideshow/pict unstable/parameter-group - unstable/lazy-require + racket/lazy-require unstable/latent-contract/defthing "../common/contract.rkt" "../common/math.rkt" diff --git a/collects/plot/plot3d/plot.rkt b/collects/plot/plot3d/plot.rkt index 43190ec3f6..d1818110df 100644 --- a/collects/plot/plot3d/plot.rkt +++ b/collects/plot/plot3d/plot.rkt @@ -6,7 +6,7 @@ unstable/contract slideshow/pict unstable/parameter-group - unstable/lazy-require + racket/lazy-require unstable/latent-contract/defthing "../common/contract.rkt" "../common/math.rkt" diff --git a/collects/racket/lazy-require.rkt b/collects/racket/lazy-require.rkt new file mode 100644 index 0000000000..d74a2a645a --- /dev/null +++ b/collects/racket/lazy-require.rkt @@ -0,0 +1,84 @@ +#lang racket/base +(require (for-syntax racket/base) + compiler/cm-accomplice + racket/runtime-path + racket/promise) +(provide lazy-require) + +(define-syntax (lazy-require stx) + (syntax-case stx () + [(lazy-require #:requires-for-path (extra-req ...) + [modpath (thing ...)] ...) + #`(begin + (lazy-require1 modpath (extra-req ...) (thing ...) #,stx) + ...)] + [(lazy-require [modpath (thing ...)] ...) + (syntax/loc stx + (lazy-require #:requires-for-path () + [modpath (thing ...)] ...))])) + +(define-for-syntax counter 0) + +(define-syntax (lazy-require1 stx) + (syntax-case stx () + [(lazy-require1 modpath (extra-req ...) (name ...) orig-stx) + (with-syntax ([(defn ...) + (for/list ([name (in-list (syntax->list #'(name ...)))]) + (unless (identifier? name) + (raise-syntax-error #f "expected identifier" #'orig-stx name)) + (with-syntax ([name name] + [(aux) (generate-temporaries (list name))]) + #`(begin (define aux (make-lazy-function 'name get-sym)) + (define-syntax name + (make-rename-transformer + (syntax-property (quote-syntax aux) + 'not-provide-all-defined #t))))))] + [define-mpi-var + (let ([phase (sub1 (variable-reference->phase (#%variable-reference)))]) + (if (zero? phase) + ;; `define-runtime-module-path-index' works right at phase-level 0: + #'(define-runtime-module-path-index mpi-var (quasiquote modpath)) + ;; need a submodule: + (with-syntax ([lazy-require-path-n + (string->symbol + (format "lazy-require-path-~a-~a" + phase + counter))]) + (set! counter (add1 counter)) + #'(begin + (module lazy-require-path-n racket/base + (require racket/runtime-path + (for-syntax racket/base) + extra-req ...) + (provide mpi-var) + (define-runtime-module-path-index mpi-var (quasiquote modpath))) + (require 'lazy-require-path-n)))))]) + ;; implicit quasiquote, so can use normal module-path syntax + ;; or escape to compute a the module-path via expression + #'(begin + define-mpi-var + (define (get-sym sym) + (parameterize ((current-namespace (variable-reference->namespace (#%variable-reference)))) + (begin0 + (dynamic-require mpi-var sym) + (do-registration (#%variable-reference) (quasiquote modpath))))) + defn ...))])) + +(define (make-lazy-function name get-sym) + ;; Use 'delay/sync' because 'delay' promise is not reentrant. + ;; FIXME: OTOH, 'delay/sync' promise is not kill-safe. + (let ([fun-p (delay/sync (get-sym name))]) + (procedure-rename + (make-keyword-procedure + (lambda (kws kwargs . args) + (keyword-apply (force fun-p) kws kwargs args))) + name))) + +(define (do-registration vr modpath) + (let ([path (resolved-module-path-name + (module-path-index-resolve + (module-path-index-join + modpath + (variable-reference->resolved-module-path vr))))]) + (when (path? path) + (register-external-module path)))) diff --git a/collects/racket/match/define-forms.rkt b/collects/racket/match/define-forms.rkt index ba607f50b7..0546421802 100644 --- a/collects/racket/match/define-forms.rkt +++ b/collects/racket/match/define-forms.rkt @@ -6,7 +6,7 @@ unstable/sequence syntax/parse syntax/parse/experimental/template - unstable/lazy-require)) + racket/lazy-require)) (begin-for-syntax (lazy-require [racket/match/patterns (bound-vars)] diff --git a/collects/racket/match/match.rkt b/collects/racket/match/match.rkt index 93ced7d355..d547ece8a2 100644 --- a/collects/racket/match/match.rkt +++ b/collects/racket/match/match.rkt @@ -7,7 +7,7 @@ define-match-expander) "define-forms.rkt" "struct.rkt" - (for-syntax unstable/lazy-require + (for-syntax racket/lazy-require (only-in "stxtime.rkt" match-...-nesting prop:match-expander diff --git a/collects/racket/place.rkt b/collects/racket/place.rkt index 81389c35d4..2d02af3eec 100644 --- a/collects/racket/place.rkt +++ b/collects/racket/place.rkt @@ -10,7 +10,7 @@ racket/place/private/th-place racket/place/private/prop racket/private/streams - unstable/lazy-require + racket/lazy-require (for-syntax racket/base diff --git a/collects/scribblings/reference/syntax.scrbl b/collects/scribblings/reference/syntax.scrbl index 06e3917b23..a97b05bca7 100644 --- a/collects/scribblings/reference/syntax.scrbl +++ b/collects/scribblings/reference/syntax.scrbl @@ -13,6 +13,9 @@ racket/package racket/splicing racket/runtime-path + racket/lazy-require + (only-in compiler/cm-accomplice + register-external-module) racket/performance-hint)) @(define require-eval (make-base-eval)) @@ -2777,3 +2780,43 @@ syntactic forms or languages that supply a more limited kind of Attaches a @racket['compiler-hint:cross-module-inline] @tech{syntax property} to each @racket[form], which is useful when a @racket[form] is a function definition. See @racket[define-values].} + +@;------------------------------------------------------------------------ +@section[#:tag "lazy-require"]{Importing Modules Lazily: @racket[lazy-require]} + +@note-lib-only[racket/lazy-require] + +@defform/subs[#:literals (unquote) + (lazy-require maybe-requires + [mod (imported-fun-id ...)] ...) + ([mod module-path + (unquote module-path-expr)] + [maybe-requires code:blank + (code:line #:requires-for-path (require-spec ...))]) + #:contracts ([module-path-expr module-path?])]{ + +Defines each @racket[imported-fun-id] as a function that, when called, +dynamically requires the export named @racket[imported-fun-id] from +the module specified by @racket[mod] and calls it with the same +arguments. + +The module @racket[mod] can be specified as a @racket[_module-path] +(see @racket[require]) or as an @racket[unquote]-escaped expression +that computes a module path. As with +@racket[define-runtime-module-path-index], a @racket[module-path-expr] +is evaluated both in phase level 0 and phase level 1 relative to its +enclosing phase level. + +If the enclosing relative phase level is not 0, then +@racket[module-path-expr] is also placed in a submodule (with a use of +@racket[define-runtime-module-path-index] at phase level 0 within the +submodule); supply extra @racket[require-spec]s with +@racket[#:requires-for-path] to bind within the submodule for +@racket[module-path-expr]. Introduced submodules have the names +@racket[lazy-require-]@racket[_n]@racketidfont{-}@racket[_m], where +@racket[_n] is a phase-level number and @racket[_m] is a number. + +When the use of a lazily-required function triggers module loading, +@racket[register-external-module] declares a potential compilation +dependency (in case the function is used in the process of compiling a +module).} diff --git a/collects/syntax/parse/experimental/reflect.rkt b/collects/syntax/parse/experimental/reflect.rkt index 809663f777..107438a902 100644 --- a/collects/syntax/parse/experimental/reflect.rkt +++ b/collects/syntax/parse/experimental/reflect.rkt @@ -1,6 +1,6 @@ #lang racket/base (require (for-syntax racket/base - unstable/lazy-require + racket/lazy-require syntax/parse/private/residual-ct) ;; keep abs.path racket/contract/base racket/contract/combinator diff --git a/collects/syntax/parse/experimental/splicing.rkt b/collects/syntax/parse/experimental/splicing.rkt index b6e026df95..de5f112a39 100644 --- a/collects/syntax/parse/experimental/splicing.rkt +++ b/collects/syntax/parse/experimental/splicing.rkt @@ -1,7 +1,7 @@ #lang racket/base (require (for-syntax racket/base syntax/parse - unstable/lazy-require + racket/lazy-require "../private/kws.rkt") syntax/parse/private/residual) ;; keep abs. path (provide define-primitive-splicing-syntax-class) diff --git a/collects/syntax/parse/private/litconv.rkt b/collects/syntax/parse/private/litconv.rkt index 29e2b71600..1f5b901cad 100644 --- a/collects/syntax/parse/private/litconv.rkt +++ b/collects/syntax/parse/private/litconv.rkt @@ -1,6 +1,6 @@ #lang racket/base (require (for-syntax racket/base - unstable/lazy-require + racket/lazy-require "sc.rkt" "lib.rkt" "kws.rkt" diff --git a/collects/syntax/parse/private/residual.rkt b/collects/syntax/parse/private/residual.rkt index b9ef9bc0a3..10fcb522b6 100644 --- a/collects/syntax/parse/private/residual.rkt +++ b/collects/syntax/parse/private/residual.rkt @@ -1,7 +1,7 @@ #lang racket/base (require (for-syntax racket/base) racket/stxparam - unstable/lazy-require) + racket/lazy-require) ;; ============================================================ ;; Compile-time diff --git a/collects/syntax/parse/private/sc.rkt b/collects/syntax/parse/private/sc.rkt index 5cc902dac7..de6d2ddf18 100644 --- a/collects/syntax/parse/private/sc.rkt +++ b/collects/syntax/parse/private/sc.rkt @@ -1,6 +1,6 @@ #lang racket/base (require (for-syntax racket/base - unstable/lazy-require) + racket/lazy-require) "keywords.rkt") ;; keep and keep as abs. path -- lazy-loaded macros produce references to this diff --git a/collects/typed-racket/base-env/prims.rkt b/collects/typed-racket/base-env/prims.rkt index d5e045fb79..1f15ee61c2 100644 --- a/collects/typed-racket/base-env/prims.rkt +++ b/collects/typed-racket/base-env/prims.rkt @@ -48,7 +48,7 @@ This file defines two sorts of primitives. All of them are provided into any mod "base-types-extra.rkt" racket/flonum ; for for/flvector and for*/flvector (for-syntax - unstable/lazy-require + racket/lazy-require syntax/parse racket/syntax racket/base diff --git a/collects/typed-racket/env/global-env.rkt b/collects/typed-racket/env/global-env.rkt index 314af04db2..b485b5af0a 100644 --- a/collects/typed-racket/env/global-env.rkt +++ b/collects/typed-racket/env/global-env.rkt @@ -5,7 +5,7 @@ (require "../types/tc-error.rkt" syntax/id-table - unstable/lazy-require) + racket/lazy-require) (provide register-type register-type-if-undefined finish-register-type maybe-finish-register-type diff --git a/collects/typed-racket/rep/free-variance.rkt b/collects/typed-racket/rep/free-variance.rkt index 77e5e793a5..2e955d7524 100644 --- a/collects/typed-racket/rep/free-variance.rkt +++ b/collects/typed-racket/rep/free-variance.rkt @@ -3,7 +3,7 @@ racket/match racket/set (for-syntax racket/base) - unstable/lazy-require + racket/lazy-require (contract-req)) ;; Ugly hack - should use units diff --git a/collects/typed-racket/rep/rep-utils.rkt b/collects/typed-racket/rep/rep-utils.rkt index 604511df93..a0febd74b3 100644 --- a/collects/typed-racket/rep/rep-utils.rkt +++ b/collects/typed-racket/rep/rep-utils.rkt @@ -5,7 +5,7 @@ (contract-req) "free-variance.rkt" "interning.rkt" unstable/struct - unstable/lazy-require + racket/lazy-require racket/stxparam (for-syntax racket/match diff --git a/collects/typed-racket/rep/type-rep.rkt b/collects/typed-racket/rep/type-rep.rkt index 7cae184855..bb2e429c7b 100644 --- a/collects/typed-racket/rep/type-rep.rkt +++ b/collects/typed-racket/rep/type-rep.rkt @@ -5,7 +5,7 @@ "rep-utils.rkt" "object-rep.rkt" "filter-rep.rkt" "free-variance.rkt" racket/match ;mzlib/etc racket/contract - unstable/lazy-require + racket/lazy-require (for-syntax racket/base syntax/parse)) ;; Ugly hack - should use units diff --git a/collects/typed-racket/types/abbrev.rkt b/collects/typed-racket/types/abbrev.rkt index 449fce6b39..8d858f4e15 100644 --- a/collects/typed-racket/types/abbrev.rkt +++ b/collects/typed-racket/types/abbrev.rkt @@ -14,7 +14,7 @@ ;; avoid the other dependencies of `racket/place` '#%place unstable/function - unstable/lazy-require + racket/lazy-require (except-in racket/contract/base ->* -> one-of/c) (prefix-in c: racket/contract/base) (for-syntax racket/base syntax/parse racket/list) diff --git a/collects/typed-racket/types/substitute.rkt b/collects/typed-racket/types/substitute.rkt index 516ff918de..55f327e61d 100644 --- a/collects/typed-racket/types/substitute.rkt +++ b/collects/typed-racket/types/substitute.rkt @@ -8,7 +8,7 @@ racket/match racket/set racket/contract - unstable/lazy-require) + racket/lazy-require) (lazy-require ("union.rkt" (Un))) (provide subst-all substitute substitute-dots substitute-dotted subst diff --git a/collects/typed-racket/types/subtype.rkt b/collects/typed-racket/types/subtype.rkt index c1fd35f24b..7a2fbe86ae 100644 --- a/collects/typed-racket/types/subtype.rkt +++ b/collects/typed-racket/types/subtype.rkt @@ -6,7 +6,7 @@ (env type-name-env) racket/match unstable/match racket/function - unstable/lazy-require + racket/lazy-require (prefix-in c: racket/contract) (for-syntax racket/base syntax/parse)) diff --git a/collects/unstable/lazy-require.rkt b/collects/unstable/lazy-require.rkt index ca62b95197..ada04ff02a 100644 --- a/collects/unstable/lazy-require.rkt +++ b/collects/unstable/lazy-require.rkt @@ -1,89 +1,9 @@ #lang racket/base (require (for-syntax racket/base) - compiler/cm-accomplice - racket/runtime-path - racket/promise) + racket/lazy-require) (provide lazy-require begin-on-demand) -(define-syntax (lazy-require stx) - (syntax-case stx () - [(lazy-require #:requires-for-path (extra-req ...) - [modpath (thing ...)] ...) - #`(begin - (lazy-require1 modpath (extra-req ...) (thing ...) #,stx) - ...)] - [(lazy-require [modpath (thing ...)] ...) - (syntax/loc stx - (lazy-require #:requires-for-path () - [modpath (thing ...)] ...))])) - -(define-for-syntax counter 0) - -(define-syntax (lazy-require1 stx) - (syntax-case stx () - [(lazy-require1 modpath (extra-req ...) (name ...) orig-stx) - (with-syntax ([(defn ...) - (for/list ([name (in-list (syntax->list #'(name ...)))]) - (unless (identifier? name) - (raise-syntax-error #f "expected identifier" #'orig-stx name)) - (with-syntax ([name name] - [(aux) (generate-temporaries (list name))]) - #`(begin (define aux (make-lazy-function 'name get-sym)) - (define-syntax name - (make-rename-transformer - (syntax-property (quote-syntax aux) - 'not-provide-all-defined #t))))))] - [define-mpi-var - (let ([phase (sub1 (variable-reference->phase (#%variable-reference)))]) - (if (zero? phase) - ;; `define-runtime-module-path-index' works right at phase-level 0: - #'(define-runtime-module-path-index mpi-var (quasiquote modpath)) - ;; need a submodule: - (with-syntax ([lazy-require-path-n - (string->symbol - (format "lazy-require-path-~a-~a" - phase - counter))]) - (set! counter (add1 counter)) - #'(begin - (module lazy-require-path-n racket/base - (require racket/runtime-path - (for-syntax racket/base) - extra-req ...) - (provide mpi-var) - (define-runtime-module-path-index mpi-var (quasiquote modpath))) - (require 'lazy-require-path-n)))))]) - ;; implicit quasiquote, so can use normal module-path syntax - ;; or escape to compute a the module-path via expression - #'(begin - define-mpi-var - (define (get-sym sym) - (parameterize ((current-namespace (variable-reference->namespace (#%variable-reference)))) - (begin0 - (dynamic-require mpi-var sym) - (do-registration (#%variable-reference) (quasiquote modpath))))) - defn ...))])) - -(define (make-lazy-function name get-sym) - ;; Use 'delay/sync' because 'delay' promise is not reentrant. - ;; FIXME: OTOH, 'delay/sync' promise is not kill-safe. - (let ([fun-p (delay/sync (get-sym name))]) - (procedure-rename - (make-keyword-procedure - (lambda (kws kwargs . args) - (keyword-apply (force fun-p) kws kwargs args))) - name))) - -(define (do-registration vr modpath) - (let ([path (resolved-module-path-name - (module-path-index-resolve - (module-path-index-join - modpath - (variable-reference->resolved-module-path vr))))]) - (when (path? path) - (register-external-module path)))) - #| begin-on-demand notes/todo diff --git a/collects/unstable/scribblings/lazy-require.scrbl b/collects/unstable/scribblings/lazy-require.scrbl index 358becb7ff..e48a912e03 100644 --- a/collects/unstable/scribblings/lazy-require.scrbl +++ b/collects/unstable/scribblings/lazy-require.scrbl @@ -11,42 +11,6 @@ @defmodule[unstable/lazy-require] -@defform/subs[#:literals (unquote) - (lazy-require maybe-requires - [mod (imported-fun-id ...)] ...) - ([mod module-path - (unquote module-path-expr)] - [maybe-requires code:blank - (code:line #:requires-for-path (require-spec ...))]) - #:contracts ([module-path-expr module-path?])]{ - -Defines each @racket[imported-fun-id] as a function that, when called, -dynamically requires the export named @racket['imported-fun-id] from -the module specified by @racket[mod] and calls it with the same -arguments. - -The module @racket[mod] can be specified as a @racket[_module-path] -(see @racket[require]) or as an @racket[unquote]-escaped expression -that computes a module path. As with -@racket[define-runtime-module-path-index], a @racket[module-path-expr] -is evaluated both in phase level 0 and phase level 1 relative to its -enclosing phase level. - -If the enclosing relative phase level is not 0, then -@racket[module-path-expr] is also placed in a submodule (with a use of -@racket[define-runtime-module-path-index] at phase level 0 within the -submodule); supply extra @racket[require-spec]s with -@racket[#:requires-for-path] to bind within the submodule for -@racket[module-path-expr]. Introduced submodules have the names -@racket[lazy-require-]@racket[_n]@racketidfont{-}@racket[_m], where -@racket[_n] is a phase-level number and @racket[_m] is a number. - -When the use of a lazily-required function triggers module loading, -@racket[register-external-module] declares a potential compilation -dependency (in case the function is used in the process of compiling a -module).} - - @defform[(begin-on-demand #:export (fun-id ...) body ...+)]{