www

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

dotlambda.scrbl (5124B)


      1 #lang scribble/manual
      2 @require[@for-label[@only-in[dotlambda
      3                              #%dot-separator
      4                              #%dotted-id
      5                              #%module-begin
      6                              #%top-interaction]
      7                     racket/stxparam]]
      8 
      9 @title{Dotted identifiers and @racket[λ<arg>.code] syntax}
     10 @author[@author+email["Suzanne Soy" "racket@suzanne.soy"]]
     11 
     12 @(begin
     13    (module orig-racket/base racket/base
     14      (require scribble/manual)
     15      (provide racket/base:#%module-begin
     16               racket/base:#%top-interaction)
     17      (define racket/base:#%module-begin (racket #%module-begin))
     18      (define racket/base:#%top-interaction (racket #%top-interaction)))
     19    (require 'orig-racket/base))
     20 
     21 @defmodulelang[dotlambda]{
     22  This @hash-lang[] language overrides @racket/base:#%module-begin and
     23  @racket/base:#%top-interaction from @racketmodname[racket/base], and splits
     24  identifiers which contain dots, following these rules:
     25  
     26  @itemlist[
     27  @item{A single dot splits the identifier, and the dot is replaced with
     28    @racket[#%dot-separator]. If an identifier is split by one or more
     29    non-consecutive dots, all the resulting identifiers, including the
     30    occurrences @racket[#%dot-separator] are placed in a syntax list, starting
     31    with @racket[#%dotted-id], so that @racket[a.b.c] gets transformed into
     32    @racket[(#%dotted-id a #%dot-separator b #%dot-separator c)].}
     33  @item{A leading dot (which is not followed by another dot) is allowed, and is
     34    replaced with @racket[#%dot-separator], like dots occurring in the middle of
     35    the identifier.}
     36  @item{A dot immediately preceded or followed by an ellipsis @racket[…] can be
     37    omitted, so that @racket[a.….b], @racket[a….b], @racket[a.…b] and
     38    @racket[a…b] are all translated to
     39    @racket[(#%dotted-id a #%dot-separator … #%dot-separator b)].}
     40  @item{Two or more dots do not split the identifier, but one of the dots is
     41    removed (i.e. it escapes the other dots).}
     42  @item{If an identifier ends with a dot, a single trailing dot is removed and
     43    the identifier is otherwise left intact (i.e. the trailing dot escapes the
     44    whole identifier).}
     45  @item{Identifiers consisting only of dots are left unchanged, as well as the
     46    following: @racket[..+], @racket[...+], @racket[..*], @racket[...*],
     47    @racket[…], @racket[…+], @racket[…*] and @racket[::...].}]
     48 
     49  Furthermore the syntax @racket[λarg₁.arg₂.….argₙ.(expr …)] is recognised as a
     50  shorthand for @racket[(λ (arg₁ arg₂ … argₙ) (expr …))], so that
     51  @racket[λx.(+ x 2)] is roughly translated to @racket[(λ (x) (+ x 2))]. If the
     52  @racket[_var] part is left empty, then it defaults to @racket[%1], @racket[%2]
     53  and so on. The number of parameters is determined from the syntactical
     54  contents of the function's body, before performing macro-expansion. The term
     55  @racket[λ.(+ %1 %2)] is therefore roughly translated to
     56  @racket[(λ (%1 %2) (+ %1 %2))]. The variable named @racket[%] can be used as a
     57  shorthand for @racket[%1], so that @racket[λ.(+ % 10)] is therefore roughly
     58  translated to @racket[(λ (%) (+ % 10))].
     59 
     60  Since this substitution is performed on the whole program, before
     61  macro-expansion, these notations are performed regardless of the context in
     62  which an expression occurs. For example, the quoted term @racket['a.b] will
     63  also get translated to @racket['(#%dotted-id a #%dot-separator b)]. In this
     64  way, the @racket[#%module-begin] from @racket[dotlambda] works a bit like if
     65  it were a reader extension.
     66 
     67  @bold{Warning:} There probably are some issues with hygiene, especially in
     68  mixed contexts (e.g. literate programs, or typed/racket programs with untyped
     69  code at phase 1). I will think about these issues and adjust the behaviour in
     70  future versions. Future versions may therefore not be 100% backward-compatible
     71  with the current version, but the general syntax of dotted identifiers should
     72  hopefully not change much.}
     73 
     74 @defform[#:kind "syntax parameter"
     75          (#%dotted-id ids-and-separators …)]{
     76  The default implementation currently translates @racket[a.b.c.d] to
     77  @racket[(d (c (b a)))], and @racket[.a.b.c] to
     78  @racket[(λ (x) (c (b (a x))))].
     79 
     80  This behaviour can be altered using @racket[syntax-parameterize]. I don't
     81  think syntax parameters can be modified globally for the whole containing file
     82  like parameters can (via @racket[(param new-value)]), so the exact mechanism
     83  used to customise the behaviour of @racket[#%dotted-id] may change in the
     84  future.}
     85 
     86 @defidform[#%dot-separator]{
     87  Indicates the presence of a (possibly implicit) dot. The original string
     88  (usually @racket["."] or the empty string @racket[""] for an implicit dot
     89  before or after an ellipsis) is normally stored in the
     90  @racket['dotted-original-chars] syntax property of the occurrence of the
     91  @racket[#%dot-separator] identifier.}
     92 
     93 @defform[(#%module-begin . body)]{Overridden form of
     94  @racket/base:#%module-begin and @racketmodname[racket/base]}
     95 
     96 @defform[(#%top-interaction . expression)]{Overridden form of
     97  @racket/base:#%top-interaction from @racketmodname[racket/base]}
     98 
     99 @include-section{typed-dotlambda.scrbl}