Applications
ExSh
experimentalA design for a Unix shell whose language is Elixir, with real concurrent pipelines.
ExSh is a design for a Unix shell whose programming language is Elixir. It would run external programs, interactive ones included, compose them into real concurrent pipelines, and be programmable with Elixir's functions, pattern matching, structs and OTP instead of a shell language.
ExSh is in design. Its specification is a draft, and nothing in it is implemented yet. This page describes what is planned.
The idea
Shells are good at stringing programs together and poor as programming languages. Elixir is the reverse. ExSh aims to be both without making either imitate the other:
ls -la /tmp | grep x | wc -l
# is read as, stored in history as, and evaluated as:
ls("-la", "/tmp") |> grep("x") |> wc("-l")
A line typed in ordinary shell syntax is rewritten into plain Elixir once, before it is evaluated. The Elixir form is what runs, what history keeps and what a script contains, so there is no hidden second language. Text pasted from a README or a model's answer should run without translation. Real shell text can also be embedded verbatim when needed.
How it is designed
- Commands are functions. Every program on
PATHbecomes an ordinary function in a generated module namedOS, so name resolution is Elixir's own. Importing a module that definessortalongsideOSis a compile error naming both, not a silent guess. - A command is a plan, not its output.
ls() |> grep("foo")builds a description of a pipeline. Running it starts every stage at once, with output streaming between them and with back-pressure, so a slow consumer stops the producer, as|does.yes() |> head(3)must terminate. - The BEAM and the OS mix in one pipe. Any Elixir stream can feed a program, and a program's output can be consumed as an Elixir stream. A pipeline built only from Elixir stages starts no OS processes. The rule throughout is to prefer the BEAM where it gives the same result, and to reach for the OS explicitly where only the OS can do the job.
- Failure is a value. A non-zero exit is a result to inspect, not an exception. A genuine programming error crashes and is seen.
- State is data. Environment, working directory, jobs, variables and functions defined at the prompt live in a supervised session rather than in global state. That makes hibernation possible: a session written to disk and restored later, possibly on another machine or under a newer ExSh, should be indistinguishable from one that ran continuously.
Child processes, pipes, pseudo-terminals and signals are delegated entirely to ExTC's process layer, so the shell itself never opens ports or manages children. The design picks a pseudo-terminal for a single interactive foreground command (vim, ssh, git rebase -i) and pipes for everything else, by a rule that is meant to be predictable.
What it is not
ExSh is not POSIX sh and will not run configure scripts. It does not read .bashrc, is not meant to be a system login shell, and does not reimplement coreutils byte for byte. Windows is out of scope.
Status
In design. The draft specification records its decisions with their reasoning and has been through a design review. A prototype of the line rewriter showed that it can be a pure text-to-text function and that it is idempotent. Some job-control questions depend on ExTC and are open there. Apu plans to use ExSh as the shell inside its project sessions once it exists.