commit e0aeea6a9bb1802f23d258fb6b2ccc90b0d395ce
parent 7d639f43627e0606a3378c992d8674d5a7406a73
Author: Georges Dupéron <georges.duperon@gmail.com>
Date: Sun, 9 Apr 2017 15:10:11 +0200
Support for multi-argument lambdas, and %1 %2 %3 … syntax. Updated documentation.
Diffstat:
4 files changed, 59 insertions(+), 19 deletions(-)
diff --git a/implementation.rkt b/implementation.rkt
@@ -1,7 +1,8 @@
#lang racket
(provide #%dotted-id
#%dot-separator
- (rename-out [new-#%module-begin #%module-begin]))
+ (rename-out [new-#%module-begin #%module-begin]
+ [new-#%top-interaction #%top-interaction]))
(require typed/racket)
@@ -43,6 +44,13 @@
. #,(fold-syntax replace-dots
#'body))]))
+(define-syntax (new-#%top-interaction stx)
+ (syntax-case stx ()
+ [(_ . body)
+ #`(#%top-interaction
+ . #,(fold-syntax replace-dots
+ #'body))]))
+
(define-for-syntax (make-λ l args e percent?)
(define percent*
(if (and percent? (>= (length args) 1))
diff --git a/lang/reader.rkt b/lang/reader.rkt
@@ -1,2 +1,2 @@
(module reader syntax/module-reader
- dotlambda/lang)
-\ No newline at end of file
+ dotlambda)
+\ No newline at end of file
diff --git a/main.rkt b/main.rkt
@@ -1,6 +1,8 @@
#lang racket
-(require dotlambda
- (except-in typed/racket #%module-begin))
+(require dotlambda/implementation
+ (except-in typed/racket
+ #%module-begin
+ #%top-interaction))
(provide (except-out (all-from-out typed/racket))
- (all-from-out dotlambda))
-\ No newline at end of file
+ (all-from-out dotlambda/implementation))
+\ No newline at end of file
diff --git a/scribblings/dotlambda.scrbl b/scribblings/dotlambda.scrbl
@@ -1,5 +1,6 @@
#lang scribble/manual
-@require[@for-label[dotlambda]]
+@require[@for-label[@only-in[dotlambda #%dot-separator #%dotted-id]
+ racket/stxparam]]
@title{Dotted identifiers and @racket[λ<arg>.code] syntax}
@author[@author+email["Georges Dupéron" "georges.duperon@gmail.com"]]
@@ -39,18 +40,46 @@
following: @racket[..+], @racket[...+], @racket[..*], @racket[...*],
@racket[…], @racket[…+], @racket[…*] and @racket[::...].}]
- Furthermore the syntax @racket[λvar.(expr …)] is recognised as a shorthand for
- @racket[(λ (var) (expr …))], so that @racket[λx.(+ x 2)] is translated to
- @racket[(λ (x) (+ x 2))]. If the @racket[_var] part is left empty, then it
- defaults to @racket[%], so that @racket[λ.(+ % 2)] is translated to
- @racket[(λ (%) (+ % 2))].}
+ Furthermore the syntax @racket[λarg₁.arg₂.….argₙ.(expr …)] is recognised as a
+ shorthand for @racket[(λ (arg₁ arg₂ … argₙ) (expr …))], so that
+ @racket[λx.(+ x 2)] is roughly translated to @racket[(λ (x) (+ x 2))]. If the
+ @racket[_var] part is left empty, then it defaults to @racket[%1], @racket[%2]
+ and so on. The number of parameters is determined from the syntactical
+ contents of the function's body, before performing macro-expansion. The term
+ @racket[λ.(+ %1 %2)] is therefore roughly translated to
+ @racket[(λ (%1 %2) (+ %1 %2))]. The variable named @racket[%] can be used as a
+ shorthand for @racket[%1], so that @racket[λ.(+ % 10)] is therefore roughly
+ translated to @racket[(λ (%) (+ % 10))].
-@section{Module language for @racket[dotlambda]}
+ Since this substitution is performed on the whole program, before
+ macro-expansion, these notations are performed regardless of the context in
+ which an expression occurs. For example, the quoted term @racket['a.b] will
+ also get translated to @racket['(#%dotted-id a #%dot-separator b)]. In this
+ way, the @racket[#%module-begin] from @racket[dotlambda] works a bit like if
+ it were a reader extension.
-@defmodulelang[dotlambda/lang]{
- This language is equivalent to
- @racket[#,(hash-lang) #,(racketmodname dotlambda)], but can also be used as
- a module language.
-}
+ @bold{Warning:} There probably are some issues with hygiene, especially in
+ mixed contexts (e.g. literate programs, or typed/racket programs with untyped
+ code at phase 1). I will think about these issues and adjust the behaviour in
+ future versions. Future versions may therefore not be 100% backward-compatible
+ with the current version, but the general syntax of dotted identifiers should
+ hopefully not change much.}
+@defform[#:kind "syntax parameter"
+ (#%dotted-id ids-and-separators …)]{
+ The default implementation currently translates @racket[a.b.c.d] to
+ @racket[(d (c (b a)))], and @racket[.a.b.c] to
+ @racket[(λ (x) (c (b (a x))))].
+ This behaviour can be altered using @racket[syntax-parameterize]. I don't
+ think syntax parameters can be modified globally for the whole containing file
+ like parameters can (via @racket[(param new-value)]), so the exact mechanism
+ used to customise the behaviour of @racket[#%dotted-id] may change in the
+ future.}
+
+@defidform[#%dot-separator]{
+ Indicates the presence of a (possibly implicit) dot. The original string
+ (usually @racket["."] or the empty string @racket[""] for an implicit dot
+ before or after an ellipsis) is normally stored in the
+ @racket['dotted-original-chars] syntax property of the occurrence of the
+ @racket[#%dot-separator] identifier.}
+\ No newline at end of file