A program-unit
consists of a sequence of definitions and expressions.
program-unit
::=
library-definition
+ [statements
]
| statements
statements
::=
statement
+
statement
::=
definition
| expression
| (begin
statement
* )
Typically a program-unit
corresponds to a single source file
(i.e.a named file in the file system). Evaluating a program-unit
first requires the Kawa processor to analyze
the whole program-unit
to determine which names are defined by the
definitions, and then evaluates each statement
in order in the context
of the defined names. The value of an expression
is normally
discarded, but may be printed out instead, depending on the evaluating context.
The read-eval-print-loop (REPL) reads one or more lines until it gets
a valid program-unit
, and evaluates it as above, except that the
values of expressions are printed to the console (as if using the
display
function). Then the REPL reads and evaluates
another program-unit
, and so on. A definition in an earlier
program-unit
is remembered and is visible in a later program-unit
unles it is overridden.
A comment in the first 2 lines of a source file may contain an encoding specification. This can be used to tell the reader what kind of character set encoding is used for the file. This only works for a character encoding that is compatible with ASCII (in the sense that if the high-order bit is clear then it’s an ASCII character), and that are no non-ASCI characters in the lines upto and including the encoding specification. A basic example is:
;; -*- coding: utf-8 -*-
In general any string that matches the following regular expression works:
coding[:=]\s*([-a-zA-Z0-9]+)
A program-unit
may contain library-definitions
.
In addition, any statements
in program-unit
comprise
an implicit library, in that it can be given a name, and referenced
from other libraries.
Certain names defined in the program-unit
can be exported,
and then they can be imported by other libraries.
For more information see Module classes.
It is recommended but not required that:
There should be at most one library-definition
in a program-unit
.
The library-name
of the library-definition
should
match the name of the source file. For example:
(define-library (foo bar) ...)
should be in a file named foo/bar.scm
.
If there is a library-definition
, there should
be no extra statements
- i.e no implicit library definition.
(It is disallowed to export
any definitions from the
implicit library if there is also a library-definition
.)
Following these recommendations makes it easier to locate
and organize libraries.
However, having multiple libraries in a single program-unit
is occasionally useful for source distribution and for testing.
The body
of a lambda
, let
, let*
,
let-values
, let*-values
, letrec
, or letrec*
expression, or that of a definition with a body consists of zero or more
definitions or expressions followed by a final expression.
(Standard Scheme requires that all definitions precede all expressions.)
body
::=
statement
*
Each identifier defined by a definition is local to the body
.
That is, the identifier is bound, and the region of the binding is the
entire body
.
Example:
(let ((x 5)) (define foo (lambda (y) (bar x y))) (define bar (lambda (a b) (+ (* a b) a))) (foo (+ x 3))) ⇒ 45
When begin
, let-syntax
, or letrec-syntax
forms
occur in a body prior to the first expression, they are spliced into the
body. Some or all of the body, including portions wrapped in
begin
, let-syntax
, or letrec-syntax
forms, may be
specified by a macro use.
An expanded body
containing variable definitions can be
converted into an equivalent letrec*
expression.
(If there is a definition following expressions you may need to
convert the expressions to dummy definitions.) For example,
the let
expression in the above example is equivalent to
(let ((x 5)) (letrec* ((foo (lambda (y) (bar x y))) (bar (lambda (a b) (+ (* a b) a)))) (foo (+ x 3))))