A compiled language asks a small ceremony of you: compile, then link, then run what was linked. The ceremony earns its keep for programs you ship — and gets in the way for the other kind of program: the ten-line tool, the quick check, the file you write to think. For those, people reach for a scripting language, and trade away every compile-time guarantee to save one command.
The next Mica release removes the trade:
mica --run tool.micaOne command compiles the file, links it, runs it, and cleans up after itself. No build directory beside your file, no cache in your home directory, no state anywhere. A Mica debug compile of a single file is a matter of milliseconds — a hello-world round trip, compile and run, finishes in about a hundredth of a second — so the mode simply recompiles every time. The fastest cache is the one you don’t need.
The scripting conventions, all of them
A script runner earns its name on conventions, not on speed. --run follows
the ones every shell user already knows:
Everything after the file belongs to the program. Arguments land in the
process unit’s ArgCount and Arg, and an optional -- separator is
accepted where a program’s own arguments begin with a dash:
$ mica --run args.mica alpha beta
count=2
first=alpha
second=betaThe program’s exit code is the exit code. Shell callers branch on $?;
under --run they see the program’s own verdict, including a runtime
failure’s non-zero exit.
The program owns standard output. On a clean compile the compiler prints nothing at all — no banner, no progress, nothing to strip before piping. Diagnostics, when there are any, arrive on standard error; warnings survive the silence rule, because a warning you never see does not exist.
A here-document is a program. --run - reads the source from standard
input:
mica --run - << 'EOF'
program Hi; imp WriteLn : std; begin WriteLn("hi"); end.
EOFShebang, and then some. A leading #! line belongs to the operating
system, and the compiler’s source preparation removes it on every road —
line numbers stay true, and the editor accepts the file exactly as the
kernel does, with no diagnostic on the addressing line. The bare spelling
mica tool.mica means the same as --run tool.mica, which makes
#!/usr/bin/env micaa working first line on every Unix, without the GNU-only env -S trick that
multi-word interpreters normally require. chmod +x tool.mica, and the file
is a command — and the bare spelling also accepts an existing file with no
extension, so the script can drop .mica, move into your PATH, and become
a command in name too.
Your libraries come along
The same release introduces the project model:
a mica.project beside your sources states which encoding they speak and
which libraries they consume. The run mode is the third consumer of that
file, after the build and the language server, and it follows the same
discovery rule both already use — the nearest mica.project up the
directory tree governs.
So a script written inside your project tree imports your libraries with no flags at all:
$ cat mica.project
{
"contracts": ["build-lib"]
}
$ mica --run twice.mica # twice.mica says: imp Twice : Numbers;
twice(21) = 42This is the quiet answer to a loud annoyance in scripting ecosystems — import paths, virtual environments, dependency pinning for a ten-line tool. The project file your build already uses is the whole configuration, and a here-document typed inside the tree gets the same treatment.
Checked scripts
The part no scripting language offers: everything the compiler knows happens
before the program runs. Type errors, format-string mismatches, unused
variables, the always-on array-bounds guard — a Mica script fails at compile
time where a Python script fails at runtime, in production, on the branch
you didn’t test. The run mode’s default is the debug tier, so checks are at
their maximum exactly where iteration happens; --optimize O2 is one flag
away when a script turns out to be a workload.
The mode stays deliberately narrow: it targets the host architecture, and it
combines with --optimize, --stdlib, --memory-class, and --tasking
only — every other flag belongs to the build and is refused with a single
line. When a script grows up, --compile --link is waiting, and the file
does not change.
When
--run shipped with 6.12.5 — the same release that brings the project
model. The
command-line reference documents the
mode, and the scripting tutorial walks
the whole road against the released compiler.