Dotted identifiers and λ<arg>.code syntax
#%dotted-id
#%dot-separator
#%module-begin
#%top-interaction
1 Typed version of dotlambda
#%module-begin
#%top-interaction
7.7

Dotted identifiers and λ<arg>.code syntax

Georges Dupéron <georges.duperon@gmail.com>

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.

syntax parameter

(#%dotted-id ids-and-separators )

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.

syntax

(#%module-begin . body)

Overridden form of #%module-begin and racket/base

syntax

(#%top-interaction . expression)

Overridden form of #%top-interaction from racket/base

1 Typed version of dotlambda

Like #lang dotlambda, but overrides #%module-begin and #%top-interaction from typed/racket/base, instead.

syntax

(#%module-begin . body)

Overridden form of #%module-begin and racket/base

syntax

(#%top-interaction . expression)

Overridden form of #%top-interaction from racket/base