Rice is a minimal embeddable scripting language for Go applications.
- Dynamic-typing
- Functional programming support
- Lightweight standard library
- Single-threaded execution
- Built-in profiler
- Verbose error-reporting
⚠️ Rice is under development and subject to changes without prior notice; there is currently no backward compatibility. Try at your own risk.
Try Rice directly in your browser: https://rice-playground.vercel.app/
An official LLM prompt is available to be attached to LLM conversations. It provides full syntax and standard library guide to the LLM models. Battle-tested on Claude, Gemini, GPT, DeepSeek, MiMo models.
Download here llm-prompt.md
list.new().append(
# Primitives
123, # integer
123.456, # float
true, # bool
"Xin chao!", # string
null, # null
# Composites
list.new(), # list
set.new(), # set
map.new(), # map
{ # map (as an Object)
name: "Vi",
"age": 9
},
func() { # function
return
}
)
strings.join("\n", ...map.new()
.put(
"Fruit 1", "Apple",
"Fruit 2", "Banana",
"Fruit 3", "Cherry",
"Fruit 4", "Durian",
"Fruit 5", "Elderberry"
)
.filter(func(entry){
typeof(entry[1]) == "String" && entry[1].toLower().include("a")
})
.entries()
.sort(func(a,b){a[1]<b[1]})
.map(func(entry){entry[0]+": "+entry[1]}))
const yes = if typeof(true) == "Bool" {
const res = "Yes";
res # The last expression is the code-block's value
} else {
"No"
};
The language guides cover everything from basic syntax to embedding Rice in Go — whether you want to learn the language or integrate Rice.
Run on Intel® Core™ i3-10105 @ 3.70 GHz, Go 1.24, Windows 11. Benchmarks executed via exec/bench_test.go with go test -bench=. -benchmem.
| Benchmark | Ops/sec | ns/op | B/op | allocs/op | Description |
|---|---|---|---|---|---|
| Fibonacci(20) | 16 | 60,194,989 | 28 MB | 395,701 | Recursive function call overhead — fib(20) |
| ForLoop(10000) | 88 | 11,334,590 | 1.8 MB | 149,627 | Tight C-style for-loop, 0..9999 sum |
| Arithmetic(5000) | 140 | 7,166,243 | 1.3 MB | 117,771 | Integer arithmetic in a loop (add/mul/div) |
| RecursionDeep(15) | 137 | 7,292,346 | 2.5 MB | 34,993 | Moderately deep recursion — fib(15) |
| StringConcat(1000) | 832 | 1,202,009 | 704 KB | 14,525 | String concatenation loop, 1000 iterations |
| Functional | 14,946 | 66,921 | 18 KB | 312 | List filter + map on 5-element dataset |
RuntimeError: unresolved reference "missing" (2:22)
| const f = func() { missing };
| .....................^
└─ at <root> (4:63-5:68)
while cannot eval script statement #3
└─ at func() (4:63-5:68)
while func()
└─ at func() (3:54-3:58)
while cannot eval declaration value
while unresolved reference "missing"
RuntimeError.Bind(source) fills line/column and a caret snippet from the script text. Frames() and Unwrap() expose the same chain for host code. Single-step the VM with Interpreter.Debug() / Step() / Position() when built with -tags rice_debug.
[Root] taken 461.492ms (100.00%) at 0:0
└─[Call] taken 284.887ms (61.73%) at 106:3869
└─[Block] taken 284.887ms (100.00%) at 8:371
└─[ForLoop] taken 284.887ms (100.00%) at 12:458
└─[Block] (x10000) taken 270.419ms (94.92%) at 12:490
└─[Call] (x10000) taken 227.73ms (84.21%) at 13:516
└─[Call] (x10000) taken 219.667ms (96.46%) at 13:516
└─[Call] (x10000) taken 203.129ms (92.47%) at 13:516
└─[Call] (x10000) taken 172.021ms (84.69%) at 13:516
└─[Call] (x10000) taken 141.024ms (81.98%) at 13:516
└─[Call] (x10000) taken 54.31ms (38.51%) at 13:516
└─[Call] (x10000) taken 14.978ms (27.58%) at 13:516
└─[Call] (x10000) taken 26.054ms (18.48%) at 15:592
└─[Call] (x10000) taken 24.048ms (11.84%) at 17:699
└─[Call] (x10000) taken 26.863ms (9.93%) at 21:818
└─[Call] taken 0s (0.00%) at 9:394
└─[Call] taken 0s (0.00%) at 10:434
...
go run ./cmd/rice run script.rice
go run ./cmd/rice run script.ricebc
go run ./cmd/rice repl [--debug]
go run ./cmd/rice build -o out.ricebc script.rice
go run ./cmd/rice disasm script.rice
go run ./cmd/rice check script.rice
run compiles a .rice script or loads a .ricebc module, then executes it. repl keeps globals across lines (--debug prints tokens, checksum, and AST). build writes a portable module; disasm prints the listing; check compiles and exits 0 or 1.
- What is the file extension of Rice script? Simply,
.rice - Does Rice support resource constraints? Time-bound limit is supported per user-defined function, native function and the overall script (via Go context)
- What kind of interpreting Rice performs? A stack bytecode VM. The compiler emits a portable
RICEmodule (seedocs/bytecode.md). - How can I extend Rice with custom Go functions? Rice is designed to be highly extensible. You can expose your own Go functions and types to the environment
| Features | Stage |
|---|---|
| Base | ✅ |
| REPL/CLI | ✅ |
| Profiler | ✅ |
| Bytecode VM | ✅ |
| LSP | ❌ |
| Playground | ✅ |

