On this page:
read
read-syntax
read/ recursive
read-syntax/ recursive
read-language
read-case-sensitive
read-square-bracket-as-paren
read-curly-brace-as-paren
read-accept-box
read-accept-compiled
read-accept-bar-quote
read-accept-graph
read-decimal-as-inexact
read-accept-dot
read-accept-infix-dot
read-accept-quasiquote
read-accept-reader
read-accept-lang
current-reader-guard
current-readtable
read-on-demand-source
port-read-handler
read-honu
read-honu-syntax
read-honu/ recursive
read-honu-syntax/ recursive

12.4 Reading

(read [in])  any
  in : input-port? = (current-input-port)
Reads and returns a single datum from in. If in has a handler associated to it via port-read-handler, then the handler is called. Otherwise, the default reader is used, as parameterized by the current-readtable parameter, as well as many other parameters.

See The Reader for information on the default reader.

(read-syntax [source-name in])  (or/c syntax? eof-object?)
  source-name : any/c = (object-name in)
  in : input-port? = (current-input-port)
Like read, but produces a syntax object with source-location information. The source-name is used as the source field of the syntax object; it can be an arbitrary value, but it should generally be a path for the source file.

See The Reader for information on the default reader in read-syntax mode.

(read/recursive [in start readtable graph?])  any
  in : input-port? = (current-input-port)
  start : (or/c char? #f) = #f
  readtable : (or/c readtable? #f) = (current-readtable)
  graph? : any/c = #t
Similar to calling read, but normally used during the dynamic extent of read within a reader-extension procedure (see Reader-Extension Procedures). The main effect of using read/recursive instead of read is that graph-structure annotations (see Reading Graph Structure) in the nested read are considered part of the overall read, at least when the graph? argument is true; since the result is wrapped in a placeholder, however, it is not directly inspectable.

If start is provided and not #f, it is effectively prefixed to the beginning of in’s stream for the read. (To prefix multiple characters, use input-port-append.)

The readtable argument is used for top-level parsing to satisfy the read request; recursive parsing within the read (e.g., to read the elements of a list) instead uses the current readtable as determined by the current-readtable parameter. A reader macro might call read/recursive with a character and readtable to effectively invoke the readtable’s behavior for the character. If readtable is #f, the default readtable is used for top-level parsing.

When graph? is #f, graph structure annotations in the read datum are local to the datum.

When called within the dynamic extent of read, the read/recursive procedure produces either an opaque placeholder value, a special-comment value, or an end-of-file. The result is a special-comment value (see Special Comments) when the input stream’s first non-whitespace content parses as a comment. The result is end-of-file when read/recursive encounters an end-of-file. Otherwise, the result is a placeholder that protects graph references that are not yet resolved. When this placeholder is returned within an S-expression that is produced by any reader-extension procedure (see Reader-Extension Procedures) for the same outermost read, it will be replaced with the actual read value before the outermost read returns.

See Readtables for an extended example that uses read/recursive.

(read-syntax/recursive [source-name    
  in    
  start    
  readtable    
  graph?])  any
  source-name : any/c = (object-name in)
  in : input-port? = (current-input-port)
  start : (or/c char? #f) = #f
  readtable : (or/c readtable? #f) = (current-readtable)
  graph? : any/c = #t
Analogous to calling read/recursive, but the resulting value encapsulates S-expression structure with source-location information. As with read/recursive, when read-syntax/recursive is used within the dynamic extent of read-syntax, the result from read-syntax/recursive is either a special-comment value, end-of-file, or opaque graph-structure placeholder (not a syntax object). The placeholder can be embedded in an S-expression or syntax object returned by a reader macro, etc., and it will be replaced with the actual syntax object before the outermost read-syntax returns.

Using read/recursive within the dynamic extent of read-syntax does not allow graph structure for reading to be included in the outer read-syntax parsing, and neither does using read-syntax/recursive within the dynamic extent of read. In those cases, read/recursive and read-syntax/recursive produce results like read and read-syntax, except that a special-comment value is returned when the input stream starts with a comment (after whitespace).

See Readtables for an extended example that uses read-syntax/recursive.

(read-language [in fail-thunk])  (any/c any/c . -> . any)
  in : input-port? = (current-input-port)
  fail-thunk : (-> any) = (lambda () (error ...))
Reads from in in the same way as read, but stopping as soon as a reader language (or its absence) is determined.

A reader language is specified by #lang or #! (see Reading via an Extension) at the beginning of the input, though possibly after comment forms. The default readtable is used by read-language (instead of the value of current-readtable), and #reader forms (which might produce comments) are not allowed before #lang or #!.

+See also Source-Handling Configuration in Guide: Racket.

When it finds a #lang or #! specification, instead of dispatching to a read or read-syntax function as read and read-syntax do, read-language dispatches to a get-info function (if any) exported by the same module. The result of the get-info function is the result of read-language if it is a function of two arguments; if get-info produces any other kind of result, the exn:fail:contract exception is raised.

The function produced by get-info reflects information about the expected syntax of the input stream. The first argument to the function serves as a key on such information; acceptable keys and the interpretation of results is up to external tools, such as DrRacket. If no information is available for a given key, the result should be the second argument.

The get-info function itself is applied to five arguments: the input port being read, the module path from which the get-info function was extracted, and the source line (positive exact integer or #f), column (non-negative exact integer or #f), and position (positive exact integer or #f) of the start of the #lang or #! form. The get-info function may further read from the given input port to determine its result, but it should read no further than necessary. The get-info function should not read from the port after returning a function.

If in starts with a reader language specification but the relevant module does not export get-info (but perhaps does export read and read-syntax), then the result of read-language is #f.

If in has a #lang or #! specification, but parsing and resolving the specification raises an exception, the exception is propagated by read-language. Having at least #l or #! (after comments and whitespace) counts as starting a #lang or #! specification.

If in does not specify a reader language with #lang or #!, then fail-thunk is called. The default fail-thunk raises exn:fail:read or exn:fail:read:eof.

A parameter that controls parsing and printing of symbols. When this parameter’s value is #f, the reader case-folds symbols (e.g., producing 'hi when the input is any one of hi, Hi, HI, or hI). The parameter also affects the way that write prints symbols containing uppercase characters; if the parameter’s value is #f, then symbols are printed with uppercase characters quoted by a \ or |. The parameter’s value is overridden by quoting \ or | vertical-bar quotes and the #cs and #ci prefixes; see Reading Symbols for more information. While a module is loaded, the parameter is set to #t (see current-load).

A parameter that controls whether [ and ] are treated as parentheses. See Reading Pairs and Lists for more information.

A parameter that controls whether { and } are treated as parentheses. See Reading Pairs and Lists for more information.

(read-accept-box)  boolean?
(read-accept-box on?)  void?
  on? : any/c
A parameter that controls parsing #& input. See Reading Boxes for more information.

A parameter that controls parsing #~ compiled input. See The Reader and current-compile for more information.

A parameter that controls parsing and printing of | in symbols. See Reading Symbols and The Printer for more information.

(read-accept-graph)  boolean?
(read-accept-graph on?)  void?
  on? : any/c
A parameter value that controls parsing input with sharing. See Reading Graph Structure for more information.

A parameter that controls parsing input numbers with a decimal point or exponent (but no explicit exactness tag). See Reading Numbers for more information.

(read-accept-dot)  boolean?
(read-accept-dot on?)  void?
  on? : any/c
A parameter that controls parsing input with a dot, which is normally used for literal cons cells. See Reading Pairs and Lists for more information.

A parameter that controls parsing input with two dots to trigger infix conversion. See Reading Pairs and Lists for more information.

A parameter that controls parsing input with ` or , which is normally used for quasiquote, unquote, and unquote-splicing abbreviations. See Reading Quotes for more information.

A parameter that controls whether #reader, #lang, or #! are allowed for selecting a parser. See Reading via an Extension for more information.

(read-accept-lang)  boolean?
(read-accept-lang on?)  void?
  on? : any/c
A parameter that (along with read-accept-reader controls whether #lang and #! are allowed for selecting a parser. See Reading via an Extension for more information.

(current-reader-guard)  (any/c . -> . any)
(current-reader-guard proc)  void?
  proc : (any/c . -> . any)
A parameter whose value converts or rejects (by raising an exception) a module-path datum following #reader. See Reading via an Extension for more information.

(current-readtable)  (or/c readtable? #f)
(current-readtable readtable)  void?
  readtable : (or/c readtable? #f)
A parameter whose value determines a readtable that adjusts the parsing of S-expression input, where #f implies the default behavior. See Readtables for more information.

A parameter that enables lazy parsing of compiled code, so that closure bodies and syntax objects are extracted (and validated) from marshaled compiled code on demand. Normally, this parameter is set by the default load handler when load-on-demand-enabled is #t.

Even when parsing is delayed, compiled code is loaded into memory. If the PLT_DELAY_FROM_ZO environment variable is set (to any value) on start-up, however, even loading from disk is delayed. If the file at path changes before the delayed code or syntax object is demanded, the read-on-demand most likely will encounter garbage, leading to an exception.

(port-read-handler in)  
(case->
 (input-port? . -> . any)
 (input-port?  any/c . -> . any))
  in : input-port?
(port-read-handler in proc)  void?
  in : input-port?
  proc : 
(case->
 (input-port? . -> . any)
 (input-port? any/c . -> . any))
Gets or sets the port read handler for in. The handler called to read from the port when the built-in read or read-syntax procedure is applied to the port. (The port read handler is not used for read/recursive or read-syntax/recursive.)

A port read handler is applied to either one argument or two arguments:

The default port read handler reads standard Racket expressions with Racket’s built-in parser (see The Reader). It handles a special result from a custom input port (see make-custom-input-port) by treating it as a single expression, except that special-comment values (see Special Comments) are treated as whitespace.

The default port read handler itself can be customized through a readtable; see Readtables for more information.

(read-honu [in])  any
  in : input-port? = (current-input-port)
Like read, but for Honu mode (see Honu Parsing).

(read-honu-syntax [source-name in])  (or/c syntax? eof-object?)
  source-name : any/c = (object-name in)
  in : input-port? = (current-input-port)
Like read-syntax, but for Honu mode (see Honu Parsing).

(read-honu/recursive [in    
  start    
  readtable    
  graph?])  any
  in : input-port? = (current-input-port)
  start : (or/c char? #f) = #f
  readtable : (or/c readtable? #f) = (current-readtable)
  graph? : any/c = #t
Like read/recursive, but for Honu mode (see Honu Parsing).

(read-honu-syntax/recursive [source-name    
  in    
  start    
  readtable    
  graph?])  any
  source-name : any/c = (object-name in)
  in : input-port? = (current-input-port)
  start : (or/c char? #f) = #f
  readtable : (or/c readtable? #f) = (current-readtable)
  graph? : any/c = #f
Like read-syntax/recursive, but for Honu mode (see Honu Parsing).