The --zo/-z mode for mzc is an improverished form of the default --make/-k mode (which is described in Compiling Modified Modules to Bytecode), because it does not track import dependencies. It does, however, support compilation of non-module source.
By default, the generated bytecode is placed in the same directory as the source file – which is not where it will be found automatically when loading the source. Use the --auto-dir flag to redirect the output to a "compiled" subdirectory, where it will be found automatically when loading the source file.
Outside of a module, top-level define-syntaxes, module, #%require, define-values-for-syntaxes, and and begin expressions are handled specially by mzc --zo: the compile-time portion of the expression is evaluated, because it might affect later expressions. (The -m or --module flag turns off this special handling.)
For example, when compiling the file containing
the class form from the scheme/class library must be bound in the compilation namespace at compile time. Thus, the require expression is both compiled (to appear in the output code) and evaluated (for further computation).
Many definition forms expand to define-syntaxes. For example, define-signature expands to define-syntaxes. In --zo mode, mzc detects define-syntaxes and other expressions after expansion, so top-level define-signature expressions affect the compilation of later expressions, as a programmer would expect.
In contrast, a load or eval expression in a source file is compiled – but not evaluated! – as the source file is compiled. Even if the load expression loads syntax or signature definitions, these will not be loaded as the file is compiled. The same is true of application expressions that affect the reader, such as (read-case-sensitive #t). The -p or --prefix flag for mzc takes a file and loads it before compiling the source files specified on the command line.
In general, a better solution is to put all code to compile into a module and use mzc in its default mode.