Note: This is a super-preliminary release; expect tons of stuff to be broken!
Currently, the best way to try Sylvan is via our dev container image.
You can download or update it by running:
docker pull oci.sylvan-lang.org/dev:0.0.1
(This is an OCI image, and so should work with any other container runtime, e.g. Buildah or Podman.)
You can create a container, mount the current working directory to /code inside it, and run commands inside it with:
docker run --rm -itv "$(pwd):/code" \
oci.sylvan-lang.org/dev:0.0.1
sylvan --help
Inside the dev container, source files and libraries will be searched for inside of /code.
/code is also the default working directory.
Let’s try making and running a “Hello, world” program.
Create a file in /code named hello_world.syl.
nvim hello_world.syl
Here, we use the Neovim text editor, which is installed and configured inside the dev container to support editing Sylvan code.
If you prefer a different text editor, it can be installed with apt.
Since the /code directory is mounted from the host, you can also use a text editor on the host machine.
Write the following code into the file, then save and exit:
pub def main() -{ OS }> () {
println("Hello, world!");
}
We can load the standard library and our code to check both for errors and then run the hello_world::main function by passing them to the sylvan binary on the command line.
sylvan std hello_world -- hello_world
At this point, you’ve seen how to get the Sylvan compiler, what a simple program looks like, and how to run it.
Documentation has not yet been written for the full Sylvan language or standard library, so at this point the best thing to do to learn more might be to poke around the src directory in the repo.
Sylvan is the software supporting my thesis.
It’s still a one-person project, and unless that changes, progress until I graduate will be directed towards thesis-relevant features.
In the next few months, these are:
-
A much faster evaluator.
The current evaluator is a tree-walking interpreter; this will be replaced by a compiler to threaded code, which is then executed in-memory.
For portability reasons, this will only execute from memory (like a compile-and-go system), but it would not be difficult to turn this into a compiler to C or assembly that gets linked to a runtime.
-
An ordered attribute grammar system.
Once this is done, the “that aspires to have” can get removed from the top of this page…
-
An extended version of nanopass attribute grammars.
This will provide additional flexibility that allows expressing programs that typically require reference attributes (journal) in an ordered attribute grammar system.
Later this year, this should include:
-
A built-in Datalog implementation, for expressing fixed-point computations more declaratively.
This will include integration with the attribute grammar system along the lines of Datalog attributes, but with particular considerations for an ordered attribute grammar system.
-
Integration between ordered attribute grammars and effects.
After graduation, I plan on continuing to use Sylvan for a significant fraction of my personal software development.
It will keep being maintained and improved to support that.
Planned long-term improvements include:
-
A self-hosting compiler.
This may happen earlier if it seems like a useful evaluation target for the thesis.
This will hopefully become an optimizing compiler that gets strongly competitive performance within the space of garbage-collected languages.
Exposing the backend of the compiler as a library would also let Sylvan serve as a convenient platform for implementing and interoperating with other languages.
-
A code formatter.
-
A documentation generator.
-
Native backends for:
- AArch64
- RISC-V with RVA23
- x86_64 with APX
- WebAssembly, targetting WASIp1
- WebAssembly, targetting the browser
-
Live programming support.
-
An LSP server.
There is already a Neovim plugin that provides in-editor errors, but this is neither as performant as nor as complete as what a language server would allow.
-
A macro system.
-
Package management and build system tooling.
These two will probably be designed to have a single unified command (along the lines of Cargo), but be separable.
The package manager has a lot of unresolved questions, mostly around the design of the centralized repos.
Centralization has compelling advantages (e.g. discoverability, auditability, uniformity of documentation), but designing an optimal repo seems unsolved.
The actual build system will probably be an implementation of redo, with some Sylvan-specific binaries injected into $PATH.
-
A foreign function interface.
I think the design that “everyone” implements (broadly, the libffi API) can be improved upon a lot, along the lines of what liballocs provides.