"Racket" is, as its own Guide puts it, more an idea about programming languages than a language in the usual sense. The #lang line at the top of a module names the language the rest of the file is written in; macros can extend a base language, and a new reader can give a language a completely different syntax. This page lists the languages that a module may name and explains how a name is turned into a language.
How a language name is found
A language name after #lang is a restricted module path: the ASCII letters and digits, _, -, + and / (not at the start or end). The reader turns it into a module path in two steps, trying the first and then the second: a reader submodule of the main module of the language ((submod name reader)), or the module name/lang/reader. For scribble/base this is scribble/base/lang/reader. The module found must export read and read-syntax, which read the rest of the file and return a module form. Because the language must be in a collection to be found, it has to be installed (raco pkg install, or a link made with raco link), except through the meta-languages below. The reader module may also export get-info, which tells tools (DrRacket, the viewer in principle) how to colour the language, which buttons to show and how to configure the run-time.
| Meta-language | Means |
|---|---|
#lang s-exp module-path | the module language is any module path; the rest of the file is S-expressions that form the body |
#lang reader module-path | a reader at any module path: it must provide read and read-syntax, and produce a module form from the rest of the file |
#lang at-exp language | the language that follows on the line, with the @ notation of Scribble switched on |
#lang planet planet-path | downloads and uses a language from the old PLaneT system |
#!name | another spelling of #lang name (so #!r6rs works as the first line of an R6RS library) |
Racket tools expect a module to start with #lang; a file that does not is read as a single expression sequence by load and the REPL.
The languages
#lang | Is | Syntax read |
|---|---|---|
racket, racket/base | the main language and its small core; see The standard library | S-expressions |
typed/racket, typed/racket/base, typed/racket/shallow, typed/racket/optional, typed/racket/no-check | Typed Racket | S-expressions with type annotations |
lazy | like racket/base but a function argument is not evaluated until its value is needed | S-expressions |
frtime | functional reactive programming: expressions re-evaluate when the values they depend on change | S-expressions |
scribble/base, scribble/manual, scribble/text, scribble/doc and others | documents and text generation; see Scribble | text with @ forms |
at-exp | the @ notation over another language | S-expressions with @ forms |
r5rs, r6rs | the Scheme standards R5RS and R6RS (not default modes of Racket: programs are in modules, R5RS and R6RS pairs are mutable pairs, and the forms and functions differ); a single-file R5RS program becomes Racket by prefixing #lang r5rs, and an R6RS library or program that starts #!r6rs can be used as a Racket module. See Scheme | S-expressions |
datalog | the Datalog logic-programming language | Datalog syntax: facts, rules head :- body., queries q(X)? and retractions fact~; % comments |
rhombus | Rhombus, a language with a conventional-looking syntax built on Racket's macro system | indentation- and bracket-based: fun f(x): x + 1 |
htdp/bsl, htdp/bsl+, htdp/isl, htdp/isl+, htdp/asl (and the older lang/htdp-…) | the teaching languages of How to Design Programs: Beginning, Intermediate and Advanced Student languages, with growing sets of forms. They add check-expect, check-within, check-error, define-struct, and restrict the language so that errors are clear | S-expressions |
plai, plai/lazy, plai/mutator, plai-typed | languages of the book Programming Languages: Application and Interpretation: define-type, type-case, test, test/exn | S-expressions |
info | the restricted language of info.rkt files | S-expressions of a fixed shape |
#lang htdp/bsl
; A Posn is a structure: (make-posn Number Number)
(define-struct posn (x y))
(define (distance-to-0 p)
(sqrt (+ (sqr (posn-x p)) (sqr (posn-y p)))))
(check-expect (distance-to-0 (make-posn 3 4)) 5)
#lang datalog
parent(john, douglas).
parent(douglas, ada).
ancestor(X, Y) :- parent(X, Y).
ancestor(X, Y) :- parent(X, Z), ancestor(Z, Y).
ancestor(john, W)?
:-, and a query ends with ?.#lang rhombus
// keyword and optional arguments: a keyword starts with ~
fun six(_, ~plus: amt = 0):
6 + amt
six("anything", ~plus: 7)
fun add1(x) :: Int:
match x
| _ :: Int : x + 1
| ~else: x
cond
| 1 == 2: "also oops"
| ~else: "sensible"
:, alternatives with |, and :: adds an annotation.Datalog, in detail
The Datalog reader's lexical rules are written in its documentation: % starts a comment that runs to the end of the line; a variable is a sequence of Unicode letters, digits and underscores that begins with an upper-case letter; an identifier is any run of printing characters that contains none of ( ) ` ' = : . ~ ? " % or a space and does not begin with a Latin capital letter (a hyphen is allowed); a string is in double quotes with the escapes \", \\ and a backslash-newline; a number is 0 or an optional - and digits with no leading zero; true and false are the booleans. A literal is a predicate symbol with an optional parenthesised list of comma-separated terms. A clause is a head literal with an optional body after :-; it is an assertion when it ends ., a retraction with ~, and a query with ?. a = b and a != b are built-in literals, and (name). imports an external predicate.
Rhombus, in detail
Rhombus builds on shrubbery notation, whose token rules are written down: comments are // to the end of the line and /* */ that nest; numbers may hold _ between digits and may be decimal, floating point (with e), hexadecimal 0x, octal 0o, binary 0b or a fraction, with #inf, #neginf and #nan for the special values; #true, #false and #void are literals; strings and byte strings (#"…") have Racket's escapes but no raw newline; an identifier is Unicode alphanumerics and _; a keyword is ~ and an identifier; and an operator is a run of symbolic characters. Grouping is by indentation, : for a block and | for alternatives. A #{…} escape lets Racket S-expressions in. The words def, fun, let, class, match, if, cond, for, import and the like are ordinary bindings of the language and not lexical.
Writing a language
- A module language is a module that exports the bindings the language gives its programs, including
#%module-begin,#%app,#%datum,#%topand#%top-interactionwhen it changes them.(provide (all-from-out racket/base) (rename-out [my-app #%app]))is the standard shape.#lang s-exp "mylang.rkt"can then use it with no further setup. - A reader is a module (usually
mylang/lang/reader.rkt) that exportsreadandread-syntax.syntax/module-readerdoes most of the work:(module reader syntax/module-reader mylang)makes a reader that reads S-expressions and puts them in a module whose language ismylang. - A collection and a package make the name available: the language
mylangis in the collectionmylang, installed withraco pkg installorraco link. - get-info makes tools treat the language well:
'color-lexerfor syntax colouring,'drracket:toolbar-buttons,'configure-runtimefor setting up printing and reading when the module runs.
Not described
Known, not yet covered
- Reference: the list of languages is the one that the Racket Guide gives (typed, lazy, frtime, scribble, r5rs, r6rs and the teaching languages named as a group) plus Datalog and Rhombus. The names of the individual teaching and course languages (
htdp/bsland relatives,plaiand relatives) and their forms are from memory: the HtDP and PLAI manuals were not downloaded. Other well-known languages made with#lang(Pollen, Rosette, Brag, Racklog, Algol 60, Hackett, Pie and others) are not covered. - Reference: the Rhombus syntax is described from the token-parsing chapter of the shrubbery notation and a demonstration file; the Rhombus reference and guide were not read, so the keyword list, the forms of the language and the rules of grouping are not described in full.
- Reference: the full protocol of
get-infoandread-language, theconfigure-runtimesubmodule,module-language-infoand the way a language is loaded byracket -lwere not described. - Viewer: only the S-expression languages, Scribble and
at-exp, Datalog and Rhombus have their own readings. A file in any other#langis read as S-expressions, which is wrong for languages with another syntax (for example, Pollen markup). The Rhombus colouring marks comments, strings, numbers, keywords~key, literals and a short list of words (def fun let class interface match if cond when unless for importand others, from memory), and treats a name followed by(as a function; indentation is not used. The Datalog colouring has no handling of the(name).import form beyond ordinary punctuation.
See also
- File structure – how a file starts
- Macros – the macros that languages are made of
- Scheme: implementations and dialects – Racket among the Schemes