Skip to content
pannousPublic

About

A new data format and programming language, WebAssembly first. Try it in the browser.

Topics

Resources

Contributing

Stars

3 stars

Watchers

1 watching

Forks

Repository files navigation

🌀 Warp

A data format that is also a programming language, compiled straight to WebAssembly GC.

contact{ name: James  age: 33 }
contact.age + 1                      // 34

The same notation holds your config, your markup and your program. Warp compiles it to WebAssembly GC structs (no linear-memory runtime, no JS glue), and the compiler is itself a WebAssembly module.

▶ Try it in your browser: nothing to install. The compiler runs locally in a Web Worker.

Why Warp

  • Even when 99% of code is written by AI we can aim for the perfect programming language:
  • ideal both for humans and AI: type save but not verbose
  • Universal and fast (via aot web assembly)
  • Highly structured and expressive:
  • Data is code. Like Lisp, but with blocks, lists, key-value pairs and tags instead of s-expressions. JSON-like, but no quotes around keys or symbols. Reads and writes JSON, XML and YAML.
  • Wasm GC first. A class Person{name:String age:i64} becomes a real (struct …) type, and the module carries full name sections. Rust hosts read these objects back as typed values (see below).
  • No silent footguns. When code could mean two things, the compiler doesn't guess quietly. It warns with the reading it took and the explicit form, or it refuses when a wrong guess would corrupt results (Footguns):
    for i in 1 upto 4 { x += i }
    warning: does `upto 4` include 4? (`..<` or `..` exclude it, `to` or `...` include it) (taking exclusive); fix: ..<
    
  • Little ceremony. Implicit it, inferred parameter and return types, Unicode operators, and English words for operators where they read better:
    square := it²
    square(3) + square(4)              // 25
    
    fib := if it < 2 then it else fib(it - 1) + fib(it - 2)
    fib(20)                            // 6765
    
  • Markup is just data.
    html{ body{ h1: "Welcome"  p: "made of data" } }
    

Install

Nothing to install: warp.pannous.com runs the compiler in your browser.

Homebrew (macOS, Linux):

brew install pannous/tap/warp

Cargo :

cargo install --locked warp-lang warp-runtime

pip (macOS, Linux; any Python 3):

pip install warp-language

Linux:
sudo apt install ./warp-lang_*_amd64.deb or sudo dnf install ./warp-lang-*.x86_64.rpm.

Prebuilt binaries (macOS arm64 and x86_64, Linux x86_64 and arm64): download the archive for your platform from the latest release and put warp and warp-runtime together on your PATH.

From source:

git clone https://github.com/pannous/warp && cd warp
CARGO_NET_OFFLINE=false cargo fetch    # once: the repository builds offline, from cargo's local cache
cargo build --release && cargo build --release -p warp-runtime   # binaries in target/release/

warp-runtime is the small runtime that standalone executables are made from; it belongs in the same folder as warp. warp rebuild pure then builds warp.wasm, the compiler written in Warp (core/), which warp pure runs.

Run

warp               # interactive console "repl"
warp help                         # all commands
warp sample.warp   # run a file, server, webapp our gui
warp build sample.warp # the standalone executable (aot native and .wasm)
warp pure sample.warp  # compiled by the compiler written in Warp (not every form yet)
warp test              # the tests under tests/, through that compiler

samples/ contains classics (game of life, Dijkstra, Levenshtein, a JSON parser, a neural net) in both a Python-like style and an idiomatic Warp style, one folder per chapter of the guide (samples/graphics, samples/sound …).

Packages

use loads a local module, or else a package of the registry warp-packages by name, fetched once into packages/:

use colors
to_hex(mix(from_hex("#ff0000"), from_hex("#0000ff"), 0.5))   # "#800080"

(use).

Rust ⇄ Wasm GC round trip

let alice = Person { name: "Alice".into(), age: 30 };
is!("class Person{name:String age:i64}; Person{name:'Alice' age:30}", alice);

is! parses, compiles, runs the module in wasmtime and reads the GC object back. The compiler emits (warp compile --wasm, simplified):

(type $Text (array (mut i8)))
(type $Person (struct (field $name (ref $Text)) (field $age i64)))
(func $main (result (ref $Person))
  i32.const 0  i32.const 5  array.new_data $Text 0   ;; "Alice" from the data segment
  i64.const 30
  struct.new $Person)
(data "Alice")

Texts are GC byte arrays; linear memory is used only to hand bytes to the host or C. Declare the Rust side with wasm_struct! { Person { name: String, age: i64 } }, or inline: wasm_object! { Person { name: String = "Alice", age: i64 = 30 } }.

Untyped data travels as one universal GC type, $Node {kind: i64, data: anyref, value: (ref null $Node)}. It mirrors the host enum Node (Text, Symbol, Number, Char, Key, List, Type, Meta, Data, Error) in src/node/mod.rs.

Status

Experimental and moving fast. Tests live in test/: Warp files run by warp test through the Warp-written compiler. The language spec lives in the wiki, and parts of it are not implemented yet. Warp began as a Rust rewrite of Wasp (C++), which follows the Python experiments Angle and english-script; its compiler is now written in Warp itself (core); Rust remains only as the native host (wasmtime, FFI). The old Rust compiler is preserved on the branch rust-bootstrap.

Feedback, issues and especially "this surprised me" reports are welcome.

License

The compiler is licensed under the GNU AGPL v3 or later; the runtime crates/warp-runtime, which goes into every program built with warp, under the MIT license, so your programs are yours. Commercial licenses of the compiler: info@pannous.com. Contributing: CONTRIBUTING.md.

About

A new data format and programming language, WebAssembly first. Try it in the browser.

Topics

Resources

Contributing

Stars

3 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages