Why :script Beats Python and Nim Where It Actually Matters
Why :script Beats Python and Nim Where It Actually Matters
Section titled “Why :script Beats Python and Nim Where It Actually Matters”Most scripting languages promise speed of writing.
Janus :script promises something rarer:
Speed of writing that survives contact with production.
Not throwaway code. Not rewrite-later code. Promotable code.
The Real Problem With Scripts
Section titled “The Real Problem With Scripts”Python scripts grow into systems. Bash scripts grow into nightmares. Ruby scripts grow into memory hogs. Nim scripts grow into clever but fragile experiments.
Every ecosystem repeats the same pattern:
- Write something quick.
- It becomes important.
- Rewrite it in something safer.
- Maintain two versions forever.
That rewrite tax is the real cost of scripting. Janus was designed to remove it.
One Language From Script to System
Section titled “One Language From Script to System”A :script file is not a toy language. It is :core with bounded sugar. Nothing more.
Every script can be converted mechanically into production code. No rewriting. No porting. No reinterpretation. Just:
janus desugar script.jans → script.janThat transformation is guaranteed to produce valid :core code. Not similar code. Not equivalent code. The exact same program, without sugar.
This rule is non-negotiable. It is the foundation of the system. We call it The Script Law:
Every
:scriptprogram must be transformable into a syntactically valid:coreprogram byjanus desugar. The transformation is purely additive; no construct in:scriptexists that cannot be expressed in:core. Promotion never requires a rewrite.
Where Python Falls Apart
Section titled “Where Python Falls Apart”Python is excellent for exploration. But fragile for operations. The problems are structural, not cultural.
Runtime Errors Instead of Compile Errors
Section titled “Runtime Errors Instead of Compile Errors”In Python: typo a regex capture → runtime failure. Pass the wrong type → runtime failure. Forget an argument → runtime failure.
In Janus: named captures are typed. Mismatches are compile-time errors. Pipelines fail before execution.
You discover errors when writing code. Not when deploying it.
Interpreter Overhead
Section titled “Interpreter Overhead”Python scripts always pay runtime tax. Startup latency. Memory floor. Runtime interpretation.
Janus scripts compile once, then cache. Second run: native binary. No interpreter. No runtime penalty. Cache-hit execution is dominated by kernel execve time, not language startup.
Scripts That Cannot Grow
Section titled “Scripts That Cannot Grow”Python scripts scale poorly. Not because Python is slow. Because structure disappears. Small scripts become tangled imports, global state, hidden side effects. Promotion to production means rewriting into something stricter.
Janus removes that step. Scripts become systems without changing languages.
Where Nim Comes Close — But Stops
Section titled “Where Nim Comes Close — But Stops”Nim is the closest competitor. Compiled. Expressive. Fast. But it solves a different problem.
Nim optimizes for language cleverness. Janus optimizes for semantic discipline. That difference matters over time.
Nim Makes Magic Easy
Section titled “Nim Makes Magic Easy”Macros. Metaprogramming. Compile-time tricks. These are powerful. They are also dangerous. Complex systems become hard to reason about. Not because Nim is flawed. Because freedom scales badly.
Janus Makes Discipline Easy
Section titled “Janus Makes Discipline Easy”Every convenience in :script is:
- Bounded — the sugar list is closed and fixed in the spec
- Visible —
janus desugarshows exactly what compiles - Reversible — promotion is mechanical, not a rewrite
Nothing exists that cannot be expressed in :core. Nothing hides execution behavior. Nothing invents authority. That constraint is the advantage.
The Actual Killer Feature
Section titled “The Actual Killer Feature”Not syntax. Not performance. Not ergonomics.
Promotion without rewriting.
That is the breakthrough. Every :script program is mechanically transformable into production code. Always. By rule. Not by convention.
Technical Advantages
Section titled “Technical Advantages”Typed Pipelines Without Overhead
Section titled “Typed Pipelines Without Overhead”Traditional pipelines:
grep ERROR log.txt | awk '{print $5}' | sort | uniqWork. Until they don’t. Failures appear late. Errors are silent. Types do not exist.
Janus pipelines:
<<p"app.log">> |> grep(r/ERROR/) |> map($_.fields()) |> group_by($5) |> count()Are:
- Type-checked — capture groups are struct fields, misspellings are compile errors
- Fused into one pass — adjacent operators compile to a single iterator walk, zero allocations between stages
- Allocation-minimal — pipeline fusion is proven by the type system
- Provenance-aware — every line carries source path + line number through arbitrary transformations
Shell Safety by Construction
Section titled “Shell Safety by Construction”Most scripting bugs are quoting bugs. Most outages start with string interpolation.
Janus does not pass shell commands as strings. It parses them. Before execution.
let result := `ls -la /etc``gzip ${log_path}`? // execute, propagate errorBacktick-delimited shell literals are tokenized at parse time, not by a shell. Argument splitting follows POSIX-like rules but is performed by the Janus parser, not by /bin/sh. There is no shell injection by default because there is no shell.
Interpolation via ${expr} produces a single argument per interpolation, regardless of whitespace. `rm ${user_input}` is safe even when user_input contains spaces or shell metacharacters.
Memory Discipline Without Garbage Collection
Section titled “Memory Discipline Without Garbage Collection”Python and Ruby depend on garbage collectors. That introduces unpredictable pauses, invisible memory behavior, hidden lifetime costs.
Janus scripts use scoped allocation. A script arena allocator is injected at entry to the synthetic main function. Temporary memory dies when scope ends. Not later. Not unpredictably. Immediately.
The implicit binding extends one stack frame. A function f called from main sees the ambient allocator. A function g called from f does not, unless f explicitly passes it. This preserves cost visibility and prevents ambient allocator pollution.
Scripts That Leave Evidence
Section titled “Scripts That Leave Evidence”After transformation. After filtering. After aggregation. Most systems lose origin data.
Janus preserves it. Every Line in a TextStream carries provenance: source path, line number, byte offset. You never ask “Where did this come from?” You already know.
Built for AI, Not Just Humans
Section titled “Built for AI, Not Just Humans”Modern scripts are often written by AI. That changes the rules.
Languages with multiple ways to do one thing, hidden runtime behavior, ambiguous semantics confuse agents. Janus intentionally limits choice. Not to reduce power. To reduce error space.
One operation. One mechanism. One visible cost. That is AI-legible code.
An agent writing Ruby has 12 ways to read a file, 4 string-formatting systems, and a method_missing runtime that can hide anything. An agent writing :script has one way to do each thing, by design. The search space is the smallest of any scripting language because we banned the duplicates that other languages accumulated by accretion.
Honest Comparison
Section titled “Honest Comparison”Where Python Still Wins
Section titled “Where Python Still Wins”- Machine learning
- Scientific computing
- Notebooks
- Web frameworks
- Data science ecosystems
That will not change quickly. Nor should it. Janus does not replace Python everywhere. It replaces Python where correctness matters more than convenience.
Where Nim Still Wins
Section titled “Where Nim Still Wins”- Compile-time metaprogramming
- Embedding scripting into applications
- Macro-heavy DSL creation
Those are real advantages. Janus targets a different space: disciplined operational systems.
The Real Positioning
Section titled “The Real Positioning”Janus :script is not a Python replacement. It is not a Nim replacement. It is something else.
A scripting layer that does not collapse when it becomes important.
That difference is subtle. Until the first time a script survives production.
The Janus Haiku for :script
Section titled “The Janus Haiku for :script”Quick to write.
Compiles once. Runs forever.
Grows without rewrite.
Getting Started
Section titled “Getting Started”# Create a scriptecho 'println("Hello from Janus")' > hello.jans
# Run it (compiles, caches, executes)janus hello.jans
# See what it compiles tojanus desugar hello.jans
# Promote to productionjanus desugar --to=core hello.jansThe :script profile ships with the Janus toolchain. No extra installation. No separate runtime. Just janus run.
Ready to write scripts that survive production? Start with the :script profile guide →