www

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

multi-id.scrbl (13064B)


      1 #lang scribble/manual
      2 @require[@for-label[multi-id
      3                     racket/base
      4                     racket/contract/base]
      5          scribble-enhanced]
      6 
      7 @title{Polyvalent identifiers with @racket[multi-id]}
      8 @author[@author+email["Suzanne Soy" "racket@suzanne.soy"]]
      9 
     10 @defmodule[multi-id]
     11 
     12 This library is implemented using literate programming. The
     13 implementation details are presented in the 
     14 @other-doc['(lib "multi-id/multi-id.hl.rkt")]
     15 document.
     16 
     17 This package helps defining identifiers with many different meanings in
     18 different contexts. An identifier can be given a meaning:
     19 
     20 @itemlist[
     21  @item{As a type expander @racket[(: foo (Listof (ident arg …)))]
     22   (see @racketmodname[type-expander #:indirect])}
     23  @item{As a @tech[#:doc '(lib "scribblings/reference/reference.scrbl")]{
     24    match expander}}
     25  @item{As a @tech[#:doc '(lib "scribblings/guide/guide.scrbl")]{macro}
     26   (i.e. when it appears in the first position of a form)}
     27  @item{As a simple identifier (i.e. used as a variable, via an
     28   @tech[#:doc '(lib "scribblings/guide/guide.scrbl")]{identifier macro})}
     29  @item{As a @racket[set!] subform}]
     30 
     31 @defform[(define-multi-id name
     32            maybe-type-expander
     33            maybe-match-expander
     34            maybe-maybe-set!+call+id
     35            fallback-clause ...)
     36          #:grammar ([maybe-type-expander
     37                      (code:line)
     38                      (code:line #:type-expander proc)]
     39                     [maybe-match-expander
     40                      (code:line)
     41                      (code:line #:match-expander proc)]
     42                     [maybe-set!+call+id
     43                      (code:line)
     44                      (code:line #:set!-transformer proc)
     45                      (code:line else)
     46                      (code:line maybe-set! maybe-call maybe-id)]
     47                     [maybe-set!
     48                      (code:line #:set! proc)]
     49                     [maybe-call
     50                      (code:line #:call proc)
     51                      (code:line #:call-id identifier)]
     52                     [maybe-id
     53                      (code:line #:id proc)
     54                      (code:line #:id-id identifier)]
     55                     [else
     56                      (code:line #:else-id identifier)
     57                      (code:line #:mutable-else-id identifier)
     58                      (code:line #:else identifier-expression)
     59                      (code:line #:mutable-else identifier-expression)]
     60                     [fallback-clause
     61                      (code:line #:??? expression)]
     62                     [??? "any struct-type-property?, without the prop:"])]{
     63  Defines @racket[name] as a 
     64  @tech[#:doc '(lib "type-expander/scribblings/type-expander.scrbl")]{
     65   type expander}, 
     66  @tech[#:doc '(lib "scribblings/reference/reference.scrbl")]{
     67   match expander}, 
     68  @seclink["set__Transformers" #:doc '(lib "scribblings/guide/guide.scrbl")]{
     69   set! transformer},
     70  @tech[#:doc '(lib
     71 "scribblings/guide/guide.scrbl")]{identifier macro}, a
     72  regular 
     73  @tech[#:doc '(lib "scribblings/guide/guide.scrbl")]{macro},
     74  some other concepts, each implemented with an arbitrary
     75  @racket[struct-type-property?],
     76  or combinations of those.
     77 
     78  In the syntax described above, each @racket[proc] should
     79  be a transformer procedure accepting a single 
     80  @racket[syntax?] argument and returning a @racket[syntax?]
     81  value, i.e. the signature of each @racket[proc] should be 
     82  @racket[(syntax? . -> . syntax?)]. Each 
     83  @racket[identifier] should be an identifier, and each 
     84  @racket[identifier-expression] should be a compile-time
     85  expression producing an identifier.
     86 
     87  The following options are currently supported:
     88  @specsubform[#:unwrap (#:??? expression)
     89               #:grammar
     90               ([??? "any struct-type-property?, without the prop:"])]{
     91   The identifier @racket[name] is a struct with the @racket[prop:???] struct
     92   type property, using the given @racket[_expression]
     93 
     94   In the syntax above, @racket[#:???] is only a placeholder; any keyword can be
     95   used, so long as prefixing the keyword's name with @racket[prop:] gives an
     96   identifier which is a @racket[struct-type-property?].}
     97  @specsubform[#:unwrap (#:type-expander proc)]{ The
     98   identifier @racket[name] acts as a 
     99   @tech[#:doc '(lib "type-expander/scribblings/type-expander.scrbl")]{
    100    type expander}, using the given @racket[proc] which
    101   should return the syntax for a type.}
    102  @specsubform[#:unwrap (#:match-expander proc)]{
    103   The identifier @racket[name] acts as a 
    104   @tech[#:doc '(lib "scribblings/reference/reference.scrbl")]{
    105    match expander}, using the given @racket[proc] which
    106   should return the syntax for a match pattern.}
    107  @specsubform[#:unwrap (#:set!-transformer proc)]{
    108   The identifier @racket[name] acts as a 
    109   @seclink["set__Transformers" #:doc '(lib "scribblings/guide/guide.scrbl")]{
    110    set! transformer}, using the given @racket[proc] which
    111   should return a @racket[syntax?] value. The @racket[proc]
    112   is used both when @racket[name] is used in a 
    113   @racket[set!] form, and when it is used as a macro or
    114   identifier macro.}
    115  @specsubform[#:unwrap (#:set! proc)]{
    116   The identifier @racket[name] acts as a 
    117   @seclink["set__Transformers" #:doc '(lib "scribblings/guide/guide.scrbl")]{
    118    set! transformer} when it is used in a @racket[set!]
    119   form, using the given @racket[proc] which should return a
    120   @racket[syntax?] value.
    121 
    122   The @racket[proc] is used only when @racket[name] is used
    123   in a @racket[set!] form, but not when it is used as a
    124   macro or identifier macro. In these cases, @racket[#:call] and 
    125   @racket[#:id], respectively, are used instead.
    126 
    127   If @racket[#:id] is not specified, but @racket[name] is used
    128   as an identifier macro, the @racket[exn:fail:syntax]
    129   exception is raised. If @racket[#:call] is not specified,
    130   but @racket[name] is used as a regular macro, the 
    131   @racket[exn:fail:syntax] exception is raised.}
    132  @specsubform[#:unwrap (#:call proc)]{
    133   The identifier @racket[name]
    134   acts as a macro when it appears in the first position of
    135   a form, using the given @racket[proc] which should return
    136   a @racket[syntax?] value.
    137 
    138   The @racket[proc] is used only when @racket[name] is used
    139   as a regular macro, but not when it is used as an
    140   identifier macro or when it is used in a @racket[set!]
    141   form. In these cases, @racket[#:id] and @racket[#:set!],
    142   respectively, are used instead.
    143 
    144   If @racket[#:set!] is not specified, but @racket[name] is
    145   used in a @racket[set!] form, the @racket[exn:fail:syntax]
    146   exception is raised. If @racket[#:id] is not specified, but
    147   @racket[name] is used as an identifier macro, the
    148   @racket[exn:fail:syntax] exception is raised.}
    149  @specsubform[#:unwrap (#:call-id identifier)]{
    150   The identifier @racket[name]
    151   acts as a macro when it appears in the first position of a
    152   form. The occurrence of @racket[name] is replaced by the
    153   given @racket[identifier], which should either be a
    154   function or a macro.
    155 
    156   When @racket[name] is used as a macro, i.e. in a form
    157   like @racket[(name . args)], the whole form is replaced
    158   by @racket[(identifier . args)]. If the identifier is
    159   itself a regular macro, then the whole 
    160   @racket[(identifier . args)] form is expanded.
    161 
    162   The @racket[identifier] is used only when @racket[name]
    163   is used as a regular macro, not when it is used as an
    164   identifier macro or as a @racket[set!] transformer.
    165   In these cases, @racket[#:id] and @racket[#:set!],
    166   respectively, are used instead.
    167 
    168   If @racket[#:set!] is not specified, but @racket[name] is
    169   used in a @racket[set!] form, the @racket[exn:fail:syntax]
    170   exception is raised. If @racket[#:id] is not specified, but
    171   @racket[name] is used as an identifier macro, the
    172   @racket[exn:fail:syntax] exception is raised.}
    173  
    174  @specsubform[#:unwrap (#:id proc)]{
    175   The identifier @racket[name] acts as an 
    176   @tech[#:doc '(lib "scribblings/guide/guide.scrbl")]{identifier macro},
    177   using the given @racket[proc] which should return a 
    178   @racket[syntax?] value.
    179    
    180   The  @racket[proc] is used only when @racket[name] is used
    181   as an identifier macro, but not when it appears in the
    182   first position of a form, nor when it is used in a 
    183   @racket[set!] form. In these cases, @racket[#:call] and
    184   @racket[#:set!], respectively, are used instead.
    185 
    186   If @racket[#:set!] is not specified, but @racket[name]
    187   is used in a @racket[set!] form, the @racket[exn:fail:syntax]
    188   exception is raised. If @racket[#:call] is not specified, but
    189   @racket[name] is used as a regular macro, the
    190   @racket[exn:fail:syntax] exception is raised.}
    191 
    192  @specsubform[#:unwrap (#:id-id proc)]{
    193   The identifier @racket[name] acts as an 
    194   @tech[#:doc '(lib
    195 "scribblings/guide/guide.scrbl")]{identifier macro}. The
    196   occurrence of @racket[name] is replaced by the given 
    197   @racket[identifier]. If the @racket[identifier] is itself
    198   an identifier macro, it is expanded again.
    199   
    200   The  @racket[identifier] is used only when @racket[name]
    201   is used as an identifier macro, but not when it appears
    202   in the first position of a form, nor when it is used in a 
    203   @racket[set!] form. In these cases, @racket[#:call] and
    204   @racket[#:set!], respectively, are used instead.
    205 
    206   If @racket[#:set!] is not specified, but @racket[name] is
    207   used in a @racket[set!] form, the @racket[exn:fail:syntax]
    208   exception is raised. If @racket[#:call] is not specified,
    209   but @racket[name] is used as a regular macro,
    210   the @racket[exn:fail:syntax] exception is raised.}
    211  
    212  @specsubform[#:unwrap (#:else-id identifier)]{
    213   The identifier @racket[name]
    214   acts as a regular macro and as an identifier macro. The
    215   occurrence of @racket[name] is replaced by the given 
    216   @racket[identifier], which should either be a function, or
    217   be both a macro and an identifier macro at the same time.
    218 
    219   When @racket[name] is used as an identifier macro, it is
    220   replaced by @racket[identifier]. If the 
    221   @racket[identifier] is itself an identifier macro, then it
    222   is expanded.
    223 
    224   When @racket[name] is used as a macro, i.e. in a form
    225   like @racket[(name . args)], the whole form is replaced by
    226   @racket[(identifier . args)]. If the identifier is itself
    227   a regular macro, then the whole 
    228   @racket[(identifier . args)] form is expanded.
    229    
    230   The @racket[identifier] is not used when @racket[name] is
    231   used in a @racket[set!] form, instead the 
    232   @racket[exn:fail:syntax] exception is raised.}
    233  
    234  @specsubform[#:unwrap (#:mutable-else-id identifier)]{
    235   The identifier @racket[name]
    236   acts as a regular macro, as an identifier macro and as a 
    237   @racket[set!] transformer. In all three cases, the
    238   occurrence of @racket[name] is replaced by the given 
    239   @racket[identifier], which should either be a function, or
    240   be a macro and an identifier macro and a @racket[set!]
    241   transformer at the same time.
    242 
    243   This option works like @racket[#:else-id], except that 
    244   @racket[name] can also be used in a @racket[set!] form.
    245 
    246   When @racket[name] is used in a @racket[set!] form like 
    247   @racket[(set! name . vals)], the whole form is replaced
    248   by @racket[(set! identifier . vals)]. If the identifier is
    249   itself a @racket[set!] transformer, then the whole 
    250   @racket[(set! identifier . vals)] form is expanded.}
    251  
    252  @specsubform[#:unwrap (#:else identifier-expression)]{
    253   The identifier @racket[name]
    254   acts as a regular macro and as an identifier macro. The
    255   occurrence of @racket[name] is replaced by the result of
    256   the compile-time expression 
    257   @racket[identifier-expression], which should either
    258   produce the syntax for a function, or the syntax for an
    259   identifier which is both a macro and an identifier macro
    260   at the same time.
    261 
    262   It is equivalent to @racket[#:else-id], except that the
    263   identifier is not constant, but is instead produced by 
    264   @racket[identifier-expression]. Note that 
    265   @racket[identifier-expression] is not a transformer
    266   function (it will not be able to access the original
    267   syntax). In other words, the compile-time contract for 
    268   @racket[identifier-expression] is @racket[syntax?], not 
    269   @racket[(syntax? . -> . syntax?)].
    270 
    271   The @racket[identifier-expression] is not used when 
    272   @racket[name] is used in a @racket[set!] form, instead the
    273   @racket[exn:fail:syntax] exception is raised.}
    274  
    275  @specsubform[#:unwrap (#:mutable-else identifier-expression)]{
    276   The identifier @racket[name] acts as a regular macro, as
    277   an identifier macro and as a @racket[set!] transformer. In
    278   all three cases, the occurrence of @racket[name] is
    279   replaced by the result of the compile-time expression 
    280   @racket[identifier-expression], which should either
    281   produce the syntax for a mutable identifier containing a
    282   function, or the syntax for an identifier which is a macro
    283   and an identifier macro and a @racket[set!] transformer at
    284   the same time.
    285 
    286   It is equivalent to @racket[#:mutable-else-id], except
    287   that the identifier is not constant, but is instead
    288   produced by @racket[identifier-expression]. Note that 
    289   @racket[identifier-expression] is not a transformer
    290   function (it will not be able to access the original
    291   syntax). In other words, the compile-time contract for 
    292   @racket[identifier-expression] is @racket[syntax?], not 
    293   @racket[(syntax? . -> . syntax?)].}}