added unstable/lazy-require

Also fixed lazy-require to capture and use correct namespace.
This commit is contained in:
Ryan Culpepper 2011-09-01 22:21:31 -06:00
parent 766e6c2f00
commit e6433084f3
7 changed files with 93 additions and 84 deletions

View File

@ -1,38 +1,28 @@
#lang racket/base #lang racket/base
(require (for-syntax racket/base) (require (for-syntax racket/base)
"private/generic/lazy-require.rkt" unstable/lazy-require
racket/runtime-path
racket/contract racket/contract
"base.rkt") "base.rkt")
(provide (all-from-out "base.rkt")) (provide (all-from-out "base.rkt"))
(define-lazy-require-definer define-postgresql "private/postgresql/main.rkt") (lazy-require
(define-lazy-require-definer define-mysql "private/mysql/main.rkt") ["private/postgresql/main.rkt"
(define-lazy-require-definer define-sqlite3 "private/sqlite3/main.rkt") (postgresql-connect
(define-lazy-require-definer define-odbc "private/odbc/main.rkt")
(define-lazy-require-definer define-openssl 'openssl)
(define-postgresql
postgresql-connect
postgresql-guess-socket-path postgresql-guess-socket-path
postgresql-password-hash) postgresql-password-hash)]
["private/mysql/main.rkt"
(define-mysql (mysql-connect
mysql-connect
mysql-guess-socket-path mysql-guess-socket-path
mysql-password-hash) mysql-password-hash)]
["private/sqlite3/main.rkt"
(define-sqlite3 (sqlite3-connect)]
sqlite3-connect) ["private/odbc/main.rkt"
(odbc-connect
(define-odbc
odbc-connect
odbc-driver-connect odbc-driver-connect
odbc-data-sources odbc-data-sources
odbc-drivers) odbc-drivers)]
['openssl
(define-openssl (ssl-client-context?)])
ssl-client-context?)
(provide/contract (provide/contract
;; Duplicates contracts at postgresql.rkt ;; Duplicates contracts at postgresql.rkt

View File

@ -1,9 +1,8 @@
#lang racket/base #lang racket/base
(require "lazy-require.rkt" (require unstable/lazy-require
racket/match racket/match
racket/file racket/file
racket/list racket/list)
racket/runtime-path)
(provide dsn-connect (provide dsn-connect
(struct-out data-source) (struct-out data-source)
connector? connector?
@ -17,13 +16,11 @@
sqlite3-data-source sqlite3-data-source
odbc-data-source) odbc-data-source)
(define-lazy-require-definer define-main "../../main.rkt") (lazy-require
["../../main.rkt" (postgresql-connect
(define-main
postgresql-connect
mysql-connect mysql-connect
sqlite3-connect sqlite3-connect
odbc-connect) odbc-connect)])
#| #|
DSN v0.1 format DSN v0.1 format

View File

@ -1,38 +0,0 @@
#lang racket/base
(require (for-syntax racket/base)
racket/runtime-path
racket/promise)
(provide define-lazy-require-definer)
(define-syntax (define-lazy-require-definer stx)
(syntax-case stx ()
[(_ name modpath)
(begin
(unless (identifier? #'name)
(raise-syntax-error #f "expected identifier" stx #'name))
#'(begin (define-runtime-module-path-index mpi-var modpath)
(define-syntax name (make-lazy-require-definer #'mpi-var))))]))
(define-for-syntax (make-lazy-require-definer mpi-var)
(lambda (stx)
(syntax-case stx ()
[(_ fun ...)
(begin
(for ([fun (in-list (syntax->list #'(fun ...)))])
(unless (identifier? fun)
(raise-syntax-error #f "expected identifier for function name" stx fun)))
(with-syntax ([(fun-p ...) (generate-temporaries #'(fun ...))]
[mpi-var mpi-var])
;; Use 'delay/sync' because 'delay' promise is not reentrant.
;; FIXME: OTOH, 'delay/sync' promise is not kill-safe.
#'(begin (define fun-p (delay/sync (dynamic-require mpi-var 'fun)))
...
(define fun (make-delayed-function 'fun fun-p))
...)))])))
(define (make-delayed-function name fun-p)
(procedure-rename
(make-keyword-procedure
(lambda (kws kwargs . args)
(keyword-apply (force fun-p) kws kwargs args)))
name))

View File

@ -4,7 +4,7 @@
racket/match racket/match
racket/place racket/place
racket/serialize racket/serialize
"lazy-require.rkt" unstable/lazy-require
"interfaces.rkt" "interfaces.rkt"
"prepared.rkt" "prepared.rkt"
"sql-data.rkt" "sql-data.rkt"
@ -31,12 +31,10 @@ where <connect-spec> ::= (list 'sqlite3 path/sym mode-sym delay-num limit-num)
(serve client-chan) (serve client-chan)
(loop))) (loop)))
(define-lazy-require-definer define-main "../../main.rkt") (lazy-require
["../../main.rkt" (sqlite3-connect
(define-main
sqlite3-connect
odbc-connect odbc-connect
odbc-driver-connect) odbc-driver-connect)])
(define (serve client-chan) (define (serve client-chan)
(match (place-channel-get client-chan) (match (place-channel-get client-chan)

View File

@ -0,0 +1,37 @@
#lang racket/base
(require (for-syntax racket/base)
racket/runtime-path
racket/promise)
(provide lazy-require
(for-syntax #%datum))
(define-syntax (lazy-require stx)
(syntax-case stx ()
[(lazy-require [modpath (thing ...)] ...)
#`(begin (define-namespace-anchor anchor)
(lazy-require1 modpath (thing ...) anchor #,stx)
...)]))
(define-syntax (lazy-require1 stx)
(syntax-case stx ()
[(lazy-require1 modpath (name ...) anchor 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))
#`(define #,name (make-lazy-function '#,name get-sym)))])
#'(begin (define-runtime-module-path-index mpi-var modpath)
(define (get-sym sym)
(parameterize ((current-namespace (namespace-anchor->namespace anchor)))
(dynamic-require mpi-var sym)))
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)))

View File

@ -0,0 +1,24 @@
#lang scribble/manual
@(require scribble/eval
"utils.rkt"
(for-label racket/base
racket/runtime-path
unstable/lazy-require))
@title[#:tag "lazy-require"]{Lazy Require}
@defmodule[unstable/lazy-require]
@unstable[@author+email["Ryan Culpepper" "ryanc@racket-lang.org"]]
@defform[(lazy-require [mod-expr (imported-fun-id ...)] ...)
#:contracts ([mod-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-expr] and calls it with the same
arguments.
As with @racket[define-runtime-module-path-index], @racket[mod-expr]
is evaluated both in phase 0 and phase 1.
}

View File

@ -88,6 +88,7 @@ Keep documentation and tests up to date.
@include-section["generics.scrbl"] @include-section["generics.scrbl"]
@include-section["hash.scrbl"] @include-section["hash.scrbl"]
@include-section["class-iop.scrbl"] ;; Interface-oriented Programming @include-section["class-iop.scrbl"] ;; Interface-oriented Programming
@include-section["lazy-require.scrbl"]
@include-section["list.scrbl"] @include-section["list.scrbl"]
@include-section["logging.scrbl"] @include-section["logging.scrbl"]
@include-section["markparam.scrbl"] @include-section["markparam.scrbl"]