7.7
Dotted identifiers and λ<arg>.code syntax
Link to this document with
@other-doc['(lib "dotlambda/scribblings/dotlambda.scrbl")]
Link to this document with
@other-doc['(lib "dotlambda/scribblings/dotlambda.scrbl")]
This
#lang language overrides
#%module-begin and
#%top-interaction from
racket/base, and splits
identifiers which contain dots, following these rules:
A single dot splits the identifier, and the dot is replaced with
#%dot-separator. If an identifier is split by one or more
non-consecutive dots, all the resulting identifiers, including the
occurrences #%dot-separator are placed in a syntax list, starting
with #%dotted-id, so that a.b.c gets transformed into
(#%dotted-id a #%dot-separator b #%dot-separator c).
A leading dot (which is not followed by another dot) is allowed, and is
replaced with #%dot-separator, like dots occurring in the middle of
the identifier.
A dot immediately preceded or followed by an ellipsis … can be
omitted, so that a.….b, a….b, a.…b and
a…b are all translated to
(#%dotted-id a #%dot-separator … #%dot-separator b).
Two or more dots do not split the identifier, but one of the dots is
removed (i.e. it escapes the other dots).
If an identifier ends with a dot, a single trailing dot is removed and
the identifier is otherwise left intact (i.e. the trailing dot escapes the
whole identifier).
Identifiers consisting only of dots are left unchanged, as well as the
following: ..+, ...+, ..*, ...*,
…, …+, …* and ::....
Furthermore the syntax λarg₁.arg₂.….argₙ. (expr …) is recognised as a
shorthand for (λ (arg₁ arg₂ … argₙ) (expr …)), so that
λx. (+ x 2) is roughly translated to (λ (x) (+ x 2)). If the
var part is left empty, then it defaults to %1, %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
λ. (+ %1 %2) is therefore roughly translated to
(λ (%1 %2) (+ %1 %2)). The variable named % can be used as a
shorthand for %1, so that λ. (+ % 10) is therefore roughly
translated to (λ (%) (+ % 10)).
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
'a.b will
also get translated to
'(#%dotted-id a #%dot-separator b). In this
way, the
#%module-begin from
dotlambda works a bit like if
it were a reader extension.
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.
The default implementation currently translates a.b.c.d to
(d (c (b a))), and .a.b.c to
(λ (x) (c (b (a x)))).
This behaviour can be altered using syntax-parameterize. I don’t
think syntax parameters can be modified globally for the whole containing file
like parameters can (via (param new-value)), so the exact mechanism
used to customise the behaviour of #%dotted-id may change in the
future.
Indicates the presence of a (possibly implicit) dot. The original string
(usually
"." or the empty string
"" for an implicit dot
before or after an ellipsis) is normally stored in the
'dotted-original-chars syntax property of the occurrence of the
#%dot-separator identifier.
1 Typed version of dotlambda
Link to this section with
@secref["Typed_version_of_dotlambda"
#:doc '(lib "dotlambda/scribblings/dotlambda.scrbl")]
Link to this section with
@secref["Typed_version_of_dotlambda"
#:doc '(lib "dotlambda/scribblings/dotlambda.scrbl")]