https://github.com/waddie/klujur
A Clojure-ish interpreted programming language
https://github.com/waddie/klujur
clojure interpreter rust slop work-in-progress
Last synced: 5 months ago
JSON representation
A Clojure-ish interpreted programming language
- Host: GitHub
- URL: https://github.com/waddie/klujur
- Owner: waddie
- License: mit
- Created: 2025-11-22T11:17:53.000Z (7 months ago)
- Default Branch: main
- Last Pushed: 2025-11-26T11:21:31.000Z (7 months ago)
- Last Synced: 2025-12-01T20:35:10.040Z (7 months ago)
- Topics: clojure, interpreter, rust, slop, work-in-progress
- Language: Rust
- Homepage:
- Size: 1.13 MB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Klujur
This is an LLM coded experiment. I don’t recommend actually using it. I was curious how far you can get prompting Claude Code (mostly Sonnet 4.5, some Opus 4.5) over a weekend to build something complex.
Klujur is an interpreted programming language modelled on [Clojure](https://github.com/clojure/clojure). Klujur is written in Rust and intended to be useful as an embedded scripting language, but also ships with a standalone CLI REPL.
## Demo

## Installation
```sh
cargo xtask install
```
`cargo` will build and install the `klujur` executable, defaulting to `~/.cargo/bin`.
## Use
```sh
# Run with rlwrap wrapper
klj
# And with the bytecode VM
klj -b
# Or the unwrapped executable, if rlwrap is unavailable
klujur
klujur -b
```
## Embedding
Add `klujur-embed` to your `Cargo.toml`:
```toml
[dependencies]
klujur-embed = { git = "https://github.com/waddie/klujur" }
```
```rust
use klujur_embed::{Engine, KlujurVal, Result};
fn main() -> Result<()> {
let mut engine = Engine::new()?;
// Evaluate code
let result = engine.eval("(+ 1 2 3)")?;
println!("{}", result); // 6
// Register native functions
engine.register_native("greet", |args: &[KlujurVal]| {
let name = match args.first() {
Some(KlujurVal::String(s)) => s.as_ref(),
_ => "World",
};
Ok(KlujurVal::string(format!("hello, {}!", name)))
});
engine.eval("(println (greet \"Klujur\"))")?; // hello, Klujur!
Ok(())
}
```
### Using the Bytecode VM
Enable the bytecode compiler for improved performance:
```rust
use klujur_embed::{Engine, Result};
fn main() -> Result<()> {
let mut engine = Engine::new()?;
// Enable bytecode compilation mode
engine.enable_bytecode_mode();
// Functions are now compiled to bytecode and executed by a stack-based VM
let result = engine.eval("((fn [x] (* x x)) 5)")?;
println!("{}", result); // 25
// Bytecode mode is particularly beneficial for:
// - Recursive functions
// - Tight loops
// - Numerical computation
let sum = engine.eval("(reduce + (range 10000))")?;
println!("{}", sum); // 49995000
Ok(())
}
```
## Intended conventions
- `.klj` extension, or `:klj` key in `.cljc` files
- `klj.edn` project files
## License
Copyright © 2025 Tom Waddington
Distributed under the MIT License. See [LICENSE file](./LICENSE) for details.