Tooling
The lyth command compiles Lyth to Go and drives the official go command for
everything else, so modules, build caching, cross-compilation, the race
detector, profilers, and debuggers work as they do for Go. The architecture is
described in compiler.
Installing
Section titled “Installing”Lyth needs Go 1.26 or newer, which it uses to build programs. With Homebrew, on macOS or
Linux (it installs Go too; brew upgrade lyth updates):
brew install lyth-lang/tap/lythWith Go, or from a checkout of the repository:
go install github.com/lyth-lang/lyth/cmd/lyth@latestgo install ./cmd/lythlyth version prints the installed version.
Commands
Section titled “Commands”| Command | What it does |
|---|---|
lyth run file.lyth [-- args] |
Builds and runs a single file, inside or outside a module. Outside a module, Lyth creates a throwaway one in your user cache. |
lyth run ./cmd/api [-- args] |
Builds and runs a main package of the current module. |
lyth build [-o out] [packages] [-- go build flags] |
Compiles packages with go build. With no packages, every directory containing .lyth files. |
lyth check [packages] |
Parses and type-checks, test files included, without running the Go compiler on the result. The fastest feedback loop. |
lyth test [packages] [go test flags] |
Compiles packages with their _test.lyth files and runs go test (testing). |
lyth vet [packages] |
Runs go vet on the generated code and maps findings to .lyth positions. |
lyth gen [-stdout | -in-tree] [packages] |
Writes the generated Go: to stdout, or next to the sources as *.lyth.go files. |
lyth mod tidy |
go mod tidy that also sees imports in .lyth files (interop). |
lyth lsp [-no-vet] |
Runs the language server on stdin and stdout, for editors (editors). |
lyth version |
Prints the compiler version. |
Common flags: -tags a,b (build tags), -diagnostics=json (one JSON object
per diagnostic, for editors and CI), -v (diagnostics include the original Go
toolchain message where one exists), -no-line-directives, and -timings
(time per compiler phase). For lyth test, -v is go test’s.
Editors
Section titled “Editors”lyth lsp is Lyth’s language server. It answers from the compiler itself:
every edit re-checks the file’s package, with unsaved changes, and
publishes the same diagnostics as lyth check, including the in-process
check of the generated Go. Saving a file also runs go vet, mapped to .lyth
lines (-no-vet turns that off). Beyond diagnostics it offers:
- Hover: the declaration as written, its doc comment, and the Go it compiles to. A Go declaration shows its doc from the Go source.
- Navigation: go to definition, including into the Go standard library and modules, type definition, references, and highlights. These follow what each name resolves to, not its text.
- Rename across the module.
- Completion: members after
.(fields, methods,lyth/coll’s extension functions, a package’s exports), the names in scope, and import paths. - Signature help.
- Inlay hints for inferred types:
x := f(), loop variables, lambda parameters, and results offunc f() = .... - Quick fixes from the compiler’s suggested edits.
- Document and workspace symbols.
- The generated Go of a file (the
lyth.showGocommand).
Editor support lives in the repository’s editors/ folder:
- VS Code (
editors/vscode-lyth): highlighting, the language server, ▶ Run and Run Test buttons,lythtasks, snippets, and a live Show Generated Go view. - Kuana (
editors/kuana-lyth): highlighting, outline, run and test buttons with test results, and the language server. Kuana’s Install button installslythwithgo install. - Other editors: the tree-sitter grammar (
editors/tree-sitter-lyth) covers highlighting, outline, indentation, and text objects. For the language server, startlyth lspfor.lythfiles, withgo.modas the root marker. In Neovim, for example:
vim.filetype.add({ extension = { lyth = "lyth" } })vim.lsp.config("lyth", { cmd = { "lyth", "lsp" }, filetypes = { "lyth" }, root_markers = { "go.mod" } })vim.lsp.enable("lyth")What a build does
Section titled “What a build does”lyth build never writes into your source tree. It generates Go into .lyth/gen
at the module root and builds with go build -overlay=.lyth/overlay.json, so
the go command sees each x.lyth as a Go file x.lyth.go in the same
directory. The .lyth/ directory ignores itself in git. If you want the
generated code committed, for example so that users of a library need no Lyth
toolchain, use lyth gen -in-tree.
lyth build -timings ./cmd/apilyth: setup 10.7mslyth: parse 0.3mslyth: load Go packages (cached) 2.1mslyth: check 0.3mslyth: lower+emit 1.3mslyth: validate 0.3mslyth: write 1.3mslyth: go build 57.3mslyth: total 73.6msMost of a build is the Go toolchain. Type information for Go dependencies comes
from go list -export and is cached in .lyth/cache keyed by the toolchain,
go.mod/go.sum, build tags, and local package contents; LYTH_NO_CACHE=1
turns the cache off. Benchmarks compares build times
with plain Go.
Diagnostics
Section titled “Diagnostics”users.lyth:13:18: error[E0202]: mismatched types float64 and int in * |13 | return price * quantity | ----- ^ -------- int | float64 | = hint: Lyth never converts numbers implicitly; write float64(quantity)Diagnostics use Lyth names and Lyth types, with codes, labels, notes, and
suggested edits. After Lyth’s own checker, the generated Go is type-checked
in-process with go/types; anything it finds (a gap in Lyth’s checker) is
reported at the exact Lyth span with code E0902, never as a raw Go error. The
design is in diagnostics.
Debugging and profiling
Section titled “Debugging and profiling”Generated code carries //line directives, so Go’s runtime reports .lyth
files and lines:
panic: runtime error: index out of range [10] with length 3
goroutine 1 [running]:main.pick(...) /home/ada/app/main.lyth:2main.main() /home/ada/app/main.lyth:7 +0x1dThe same goes for go vet findings, race reports, pprof profiles, test
failures, and breakpoints in delve, which resolves Lyth lines through the line
tables the directives produce. Local variables keep their Lyth names.
Build tags, platforms, and Go flags
Section titled “Build tags, platforms, and Go flags”Build tags, GOOS/GOARCH, CGO_ENABLED, and GOFLAGS come from the
environment as for Go. A file named net_linux.lyth is Linux-only, like
net_linux.go. Flags after -- go to go build:
GOOS=linux GOARCH=arm64 lyth build -o app ./cmd/apilyth build ./cmd/api -- -race -trimpath