www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

chain-module-begin.scrbl (2775B)


      1 #lang scribble/manual
      2 @require[@for-label[chain-module-begin
      3                     racket/base]]
      4 
      5 @title{Chaining module languages}
      6 @author[@author+email["Suzanne Soy" "racket@suzanne.soy"]]
      7 
      8 @defmodule[chain-module-begin]
      9 
     10 This package is experimental. Later versions may break backward-compatibility.
     11 
     12 @defform[(chain-module-begin lang . body)]{
     13  This macro is intended to be used as the result of a @racket[#%module-begin]
     14  macro. It chain-calls the @racket[#%module-begin] of @racket[lang]. This makes
     15  it possible for a @racket[#%module-begin] to perform some changes on its body,
     16  and then chain-call the @racket[#%module-begin] of a user-specified language.
     17 
     18  As an example here is the definition for a no-op language, which simply takes a
     19  (possibly improper) list of languages to chain, and calls the next one:
     20 
     21  @racketblock[
     22  (module the-meta-lang racket/base
     23    (provide (rename-out [new-#%module-begin #%module-begin]))
     24 
     25    (require chain-module-begin
     26             (for-syntax racket/base
     27                         syntax/parse))
     28 
     29    (define-syntax (new-#%module-begin stx)
     30      (syntax-parse stx
     31        [(_ {~or next-lang:id (next-lang:id . chain₊)} . body)
     32         (define maybe-chain₊ (if (attribute chain₊)
     33                                  `(,#'chain₊)
     34                                  '()))
     35         (define new-form `(,#'chain-module-begin ,#'next-lang ,@maybe-chain₊
     36                                                  . ,(transform-body #'body)))
     37         (datum->syntax stx new-form stx stx)]))
     38 
     39    (define-for-syntax (transform-body body)
     40      (code:comment "identity transformation:")
     41      body))]
     42 
     43  This language could then be used as follows:
     44 
     45  @racketblock[
     46  (module b the-meta-lang typed/racket
     47    (define x : Number 123))]
     48 
     49  Given two other meta-language built in the same way and provided by
     50  @racketid[meta-two] and @racketid[meta-three], it would be possible
     51  to chain the three languages as follows:
     52 
     53  @racketblock[
     54  (module b the-lang (meta-two meta-three . typed/racket)
     55    (define x : Number 123))]
     56  
     57  The @racket[chain-module-begin] macro produces the following syntax:
     58 
     59  @racketblock[(#%plain-module-begin
     60                (require lang)
     61                (continue . internal-args))]
     62 
     63  where @racket[(continue . _internal-args)] fully expands
     64  @racket[(#%module-begin . body)], where @racket[#%module-begin] is the one
     65  provided by @racket[lang], and produces the following syntax:
     66 
     67  @racketblock[(begin . _expanded-body)]
     68 
     69  An extra scope is added to the whole @racket[(begin . _expanded-body)] form,
     70  so that a @racket[#%require] form within the @racket[_expanded-body] may
     71  shadow bindings provided by @racket[lang], just as @racket[require] forms
     72  normally have the possibility to shadow bindings provided by the @(hash-lang)
     73  language.}