Yulang
Yulang is an experimental programming language that makes algebraic effects and handlers feel like ordinary control flow.
The surface looks like a small expression-oriented scripting language: it has method syntax, compact block notation, structs, enums, roles, user-defined operators, loops, early return, and references. The unusual part is that many features usually fixed in the core language are expressed through effects, handlers, roles, and standard-library code.
Yulang is alpha-stage research software. The interpreter, playground, standard library, and language server are usable enough to try real examples, but syntax, type display, effect semantics, native lowering, and library APIs may still change.
Japanese: README.ja.md
Try It
The fastest way to try Yulang is the browser playground:
To use the CLI locally, install the binary and the embedded standard library:
Run a file with the interpreter:
The smallest complete program prints a user-facing string with say:
say "Hello, World"
run executes the program and only prints output produced by the program
itself, such as say / println. To inspect root expression values while
experimenting, add --print-roots.
Check a file and print inferred public types:
Try the native backend:
The standard library is normally installed to
~/.yulang/lib/yulang-0.1.0/std. yulang run, yulang check, and
yulang server can also install the embedded standard library automatically
on first use when neither YULANG_STD nor a nearby lib/std is available.
To use a different standard-library checkout:
A First Look
use std::undet::*
struct point { x: int, y: int } with:
our p.norm2 = p.x * p.x + p.y * p.y
if all [1, 2, 3] < any [2, 3, 4]:
point { x: 3, y: 4 } .norm2
else:
0
The condition all [1, 2, 3] < any [2, 3, 4] is not special syntax.
all and any are ordinary library functions that produce nondeterministic
values. Lowering inserts junction::junction so the surrounding if receives
a real bool.
Mutable state, early return, loops, and effectful conditions use the same basic idea: familiar notation on the surface, typed effects and small library abstractions underneath.
Where To Read Next
- docs/language/overview.md: the main language overview.
- docs/language/overview.ja.md: Japanese language overview.
- docs/status.md: support status across parser, inference, interpreter, playground, and native backend.
- docs/native-backend.md: native backend support, CLI notes, and current limits.
- docs/native-experimental-release.md: release-gate notes for the current opt-in native subset.
- web/docs/reference/type-theory.md: public reference for effect rows, handler hygiene, and hidden handler evidence.
- docs/hidden-effect-evidence.ja.md: implementation notes for hidden effect evidence.
- examples/: runnable Yulang examples.
- lib/std/: the standard library written in Yulang.
Good first examples:
examples/showcase.yu: broad syntax and library tour.examples/06_undet_once.yu: nondeterminism through library effects.examples/10_effect_handler.yu: algebraic effect handlers.examples/04_sub_return.yu: local early return throughsub:.examples/11_attached_impl.yu: attached role implementations.
Language Server
Start the language server with:
Current language-server support includes:
- hover for inferred values, locals, methods, and many type references;
- semantic tokens;
- document symbols;
- parser, lowering, and type diagnostics;
relatedInformationon many type errors.
Zed support lives in yulang-zed/. The extension is not published
through the Zed extension registry yet; install it as a dev extension and
select the yulang-zed directory. When a yulang binary is available in the
worktree environment or in ~/.cargo/bin, the extension starts
yulang server automatically.
The old yulang-ls binary is a deprecated stub that delegates to
yulang server.
Native Backend
Native execution is an experimental backend with an explicit subset. The normal user-facing entrypoint is:
yulang native remains available for artifact generation and backend
debugging. The interpreter is still the semantic reference; the native backend
is an opt-in execution path rather than a replacement. See
docs/native-backend.md for the supported programs,
CLI details, and known limits. The current release-gate checklist and suggested
release note live in
docs/native-experimental-release.md.
The current native effects path covers string/list/bytes/path/range primitives via
runtime helper symbols. CPS repr native also preserves handler prompt exits across
effectful call return frames, so Display/Debug list construction, loop with
if results, for body if var writes, and range iteration with console effects
match the interpreter in the covered regression cases. Captured resumptions also
rebase handler return-frame thresholds, covering indexed ref update continuations
in CPS repr native. Unit-typed scalar roots display as () in the JIT display
helper even though the scalar ABI carries them as 0. Effectful thunk forcing in
the JIT also preserves the pushed post-continuation frame while the thunk body is
evaluated, so recursive handler/resumption flows can return heap values such as
tuples without leaking visible thunk handles. Scoped routed jumps only leave the
current native activation when they need to restore an outer return-frame prefix,
which keeps open-range for/last exits from continuing recursive folds while
still allowing root value arms and nondeterministic list collection to run their
local continuations. Recursive tuple-returning handlers, block-tail loop
control, native root pretty-print for unit/bool values, open-range nondet
.once, and combined junction + finite nondet + method-call roots are covered
by regressions. Native remains experimental and opt-in, but the current release
gate for the documented effects subset is clear.
Development
Run representative Rust test suites:
Build the playground locally:
Run an inline Yulang program:
Repository Layout
crates/yulang: CLI.crates/yulang-parser: parser and syntax tree support.crates/yulang-sources: source sets, realms, compilation units, and syntax artifacts.crates/yulang-typed-ir: typed intermediate representation and principal-type evidence.crates/yulang-infer: type inference and principal-type export.crates/yulang-runtime: runtime IR, monomorphization, and interpreter.crates/yulang-native: native backend.crates/yulang-wasm: WebAssembly API used by the playground.examples: executable examples for the current language implementation.lib/std: standard library written in Yulang.web/playground: Vite-based browser playground.web/docs: reference documentation.notes: bug, refactor, and progress notes.
Status
Yulang is pre-release research software. Syntax, type output, runtime IR, the interpreter, and the standard library may change without compatibility promises. docs/status.md describes the current support matrix; broader limitations are noted there and in docs/native-backend.md.
License
Licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE)
- MIT License (LICENSE-MIT)
at your option.