Releases: beelang-project/bee
Release list
v0.3.1
Full Changelog: v0.3.0...v0.3.1
v0.3.0
[0.3.0] — 2026-08-07
The interoperability release. BeeLang can now call C and C++ libraries without
rebuilding the interpreter: native modules import like any other module,
beegen generates the binding for you from a header, and buffers give
bulk data somewhere to live that isn't a million boxed Values — and cross the
native boundary without a copy. OpenCV 4.6 was bound and driven end to end to
prove the set is sufficient for a real library, not just a toy one. 178 checks,
up from 100.
Added
-
Native modules. A shared library can now be imported like any other
module, so calling a C or C++ library no longer means rebuilding the
interpreter:extern "C" const char* bee_native_abi() { return BEE_NATIVE_ABI; } extern "C" int bee_module_init(bee::NativeModule* m) { m->def("add", 2, [](bee::Interpreter&, std::vector<bee::Value>& a) { return bee::Value(bee::native::num(a[0], "add", 0) + bee::native::num(a[1], "add", 1)); }); return 0; }
import demofindsdemo.so(.dll,.dylib) through the same lookup as a
.beefile, including inside an installed package — so a hive package can ship
a compiled module.src/bee_native.hppis the API, with
conversion helpers that report a bad argument as a normal BeeLang error, with a
stack trace. -
beegen, a binding generator. It reads C++ headers with libclang and
writes a native module plus an idiomatic BeeLang wrapper:beegen shapes.hpp --module shapes && ./build.shFree functions, classes (constructors, methods, public fields, statics) and
enums are mapped; C++ classes become BeeLang classes holding an opaque handle,
enums become dicts. Every declaration it can't map is reported with a
reason — templates, variadics, out-parameters, unbound types — because a
binding that silently omits half a library is worse than one that says so.
It also writeshive.json, so a binding installs like any other package. Full
documentation in docs/BINDINGS.md.libclang is loaded at run time through a hand-declared slice of its stable C
ABI, so building BeeLang needs no clang headers or libraries at all. -
Buffers: a contiguous typed array. BeeLang's answer to an ndarray, and the
type bulk data travels in:let img = zeros([480, 640, 3], "u8") # 900 KB contiguous, not 15 MB of Values print(img) # buffer<u8>[480,640,3] [0, 0, ...]f32/f64/i8/u8/i16/u16/i32/i64, flat[]indexing plusat/
set_atper dimension,zeros/ones/full/buffer_from/to_list,
shape/dtype/byte_len,reshape/astype/copy/fill, and
buf_add/sub/mul/div/sum/min/max. Buffers compare by contents and
print with a preview rather than a million elements. -
Zero-copy buffers across the native boundary. A shim declares a parameter
asBeeBuffer— a plain C struct in the newbee_buffer.h
that needs no BeeLang header — andbeegenhands the buffer's own memory over
by pointer. This is what makes binding an image or tensor library practical
rather than merely possible. -
Native code can call back into BeeLang.
bee::native::callback()wraps a
BeeLang function so a library's log or progress hook can invoke it, with
GilLockfor callbacks arriving on the library's own threads andGilOfffor
handing the lock back during a long call. The interpreter is now linked with
-rdynamicso a module can resolveInterpreter::callValue. -
Class hierarchies and factory-made interfaces. A derived handle is accepted
where a base is expected, through a registeredstatic_cast(so the pointer is
adjusted correctly even under multiple inheritance). Abstract classes get no
constructor and nofree()— their instances come from a factory function and
are released by the API's owndestroy(). This is the shape TensorRT and ONNX
Runtime expose, and it is now bindable directly. -
std::vector<T>maps to a list in both directions, for numeric, bool and
string elements. -
Wrappers adopt factory handles.
new Image(vision.imread("cat.png"))works
as well asnew Image(): a generated wrapper either constructs a new object or
takes over a handle a factory function returned. Library APIs of any size are
full of factories, so a wrapper that could only construct could not be used
with them at all. -
Verified against a real library. OpenCV 4.6 was bound through a 40-line
shim and driven from BeeLang end to end -- pixels built in a buffer, handed to
OpenCV with no copy, resized, converted, blurred, Canny-detected, written as a
PNG, read back and pulled into a buffer again. -
C++ default arguments become optional BeeLang arguments:
beegenemits one
native entry point per callable arity and the wrapper dispatches on how many
arguments it was given, so the C++ compiler supplies the defaults and beegen
never has to parse them. -
tests/beegen_test.sh— 53 checks covering generation, the skip report, the
wrapper's shape, compiling the generated module, calling it from BeeLang, the
boundary errors (wrong type, wrong arity, wrong handle, use-after-free), and
the capability set above against a header shaped like a real inference API.
Changed
-
The
.deband Windows installer also installbeegen, and the.debnow
ships BeeLang's headers under/usr/include/beeso native modules can be
compiled against an installed interpreter. -
The VS Code extension moved to its own repository,
beelang-project/vscode-bee,
with its history intact. It waseditors/vscode-bee/, which tied its releases
to the interpreter's — thevscode-beelang-v0.1.0tag matched this repo's
v*release trigger and tried to build a.debout of it. Editor tooling and
the language now version and ship independently. The release trigger here is
narrowed tov[0-9]*so only interpreter versions fire it.
Fixed
- A C++ parameter named like a BeeLang keyword (
in,class,fromare all
ordinary C++ names) generated code that would not parse. Such names now get a
trailing underscore. - A C++ library's own exception no longer aborts the process.
cv::Exception,
Ort::Exception,std::bad_allocand friends thrown inside a native call are
converted to a BeeLang runtime error with a stack trace. Bee-levelthrowand
control flow still pass through built-ins that call back into Bee code. hive installnow refuses to install a package into its own source tree
(which producedgreet/hive_modules/greet, helping nothing) and never records
a package as depending on itself.--forceoverrides the first if you really
mean it.
Known limitations
beegenneeds libclang at run time — not to build BeeLang, but to read a
header. Without it (apt install libclang-18-dev, or--libclang <path>) it
says so and stops. Everything else, including running generated bindings,
works without it.- Not every declaration can be bound. Templates, variadics, out-parameters
and types beegen can't map are skipped — reported individually, with a reason,
rather than silently dropped. Hand-write a shim for those; the OpenCV binding
needed 40 lines of one. - Buffers are dense and contiguous only: no strides, no views, no broadcasting.
reshapeand slicing a buffer copy. - The Windows installer still ships an interpreter-only build (no JIT), and now
no libclang either, sobeegenon Windows needs one installed separately. - Carried from 0.2.0: no public registry is running, so
hive install <name>
needs a--registry;hive publishdoesn't exist; the REPL has no line
editing or history.
Full Changelog: v0.2.0...v0.3.0
beelang-v0.1.1
Changelog
All notable changes to BeeLang are documented here. The format is based on
Keep a Changelog, and this project
adheres to Semantic Versioning.
[0.1.1] — 2026-08-06
Performance work focused on loops, condition checking, and string building. No
language or API changes — existing programs run identically, only faster. All
14 examples and the correctness suites pass unchanged.
Performance
- Inline cache for global variables. Reads/writes of top-level (named)
variables now go through a cached pointer instead of astd::maplookup on
every access. Top-level loops that were ~3.7× slower than Python are now
~2.7× faster than before this change. - Cross-function JIT. The native JIT previously handled only direct
self-recursion; it now compiles a whole numeric call graph — helpers and
mutual recursion — into one module, so those calls are direct and
inlinable. A helper-calling loop (e.g. a prime sieve) that used to fall back
to the interpreter now runs ~6× faster than Python. - Top-level loops are JIT-compiled automatically. A numeric top-level
while/forno longer needs to be wrapped in a function to hit native
speed. The numeric globals a loop touches are passed as an in/out array,
loaded on entry and written back only on clean completion; anything
non-numeric (aprint, a string, division by zero) transparently falls back
to the interpreter from unmodified state. A 10 M-iteration top-level loop
dropped from ~1.84 s to ~0.03 s (~16× faster than Python). - In-place string append. The
x = x + rhs/x += rhsidiom was O(n²) —
a fresh, growing string each iteration (~246× slower than Python). It now
grows the buffer in place when the string is not aliased, falling back to a
copy to preserve value semantics otherwise. Building a 200 k-character string
went from ~2.46 s to ~0.03 s (~82× faster). - JIT warmup guard. A small, flat
forloop with a compile-time-known trip
count below ~40 k now runs interpreted instead of paying the ~3 ms one-time
native compilation, which for such loops costs more than it saves. Nested,
large, or unanalyzable loops still compile as before. A 10 k-iteration loop
dropped from ~4.3 ms to ~0.5 ms, matching Python. - Void numeric functions no longer run twice. A function that falls off the
end (no value-returningreturn) used to be compiled, executed natively, then
discarded and re-run in the interpreter — doubling the work. Native completion
now reports a nil result directly, so such functions keep their native run. A
100 M-iteration side-effect-free function dropped from ~6 s to milliseconds;
a 10 M-iteration accumulating loop runs ~20× faster than Python.
Full Changelog: v0.1.0...v0.1.1
beelang-v0.1.0
Changelog
All notable changes to BeeLang are documented here. The format is based on
Keep a Changelog, and this project
adheres to Semantic Versioning.
[v0.1.0] — 2026-08-06
The first public release of BeeLang — a small, friendly scripting language with
a built-in native (LLVM) JIT. 🐝
Language
- Dynamically-typed values:
nil, booleans, numbers (64-bit float), strings,
lists, and dicts. - Variables with
let, lexical scoping, and block/function/loop scopes. - Full operator set: arithmetic, comparison, logical (
and/or/notwith
&&/||/!aliases), and compound assignment (+=,-=,*=,/=). - Control flow:
if/else if/else,while, C-stylefor, and
for … inover lists, strings, and dicts, plusbreak/continue. - First-class functions and closures.
- Classes with single inheritance (
extends),this,super, aninit
constructor, and a customizablestr()for printing. - A module system:
import,import … as,from … import, and
from … import *, resolved relative to the file and a siblinglib/folder. - Error handling with
try/catch/finallyandthrowof any value. - Two comment styles (
#and//) and an optional statement terminator (;).
Runtime & performance
- Compact C++17 runtime with no required third-party dependencies.
- Built-in LLVM ORCv2 JIT (enabled by default when LLVM 17/18 is present):
functions within a numeric subset are compiled to native code operating on
unboxed doubles, transparently falling back to the runtime for everything
else.fib(32)drops from ~11 s to ~0.014 s. bee --version/-vandbee --help/-h.
Standard library (no imports required)
- I/O:
print,write,input. - Conversion & inspection:
len,type,str,repr,num,int,
bool. - Math:
abs,floor,ceil,round,sqrt,pow,min,max,
range. - Files:
read_file,read_lines,write_file,append_file,
file_exists,remove_file,make_dir,list_dir. - Time & randomness:
clock,time,now,format_time,sleep,
random,random_int,random_range,random_choice,random_seed. - Environment & processes:
env,set_env,args,exec. - Threads:
spawn/joinwith a global interpreter lock (GIL) — safe
shared state and real overlap for I/O-bound work. - Type methods for strings, lists, and dicts (
upper,split,push,pop,
keys,has,get, …).
Tooling & packaging
Makefilebuild with automatic LLVM JIT detection and an overridable
VERSION.- Debian/Ubuntu
.debpackage (packaging/build-deb.sh)
built with the JIT; dependencies are auto-detected. - Windows installer (
packaging/windows/) via Inno
Setup — addsbeetoPATH, associates.be/.beefiles, and registers
an uninstaller. - GitHub Actions release workflow that builds both packages and publishes
them on a version tag.
Editor support
- VS Code extension (
editors/vscode-bee/) with
syntax highlighting, completions (keywords, built-ins, type methods, and file
symbols), hovers, snippets, and a bee icon for.be/.beefiles.
Documentation & examples
- Full language reference.
- A topic-by-topic set of 14 runnable examples.
Known limitations
- The Windows installer ships an interpreter-only build (no JIT yet).
- The
.debrequireslibllvm18, available on Ubuntu 24.04 and newer. - No anonymous/lambda functions — pass named functions (e.g. to
spawn).
🐝 BeeLang VS Code Extension v0.1.0
The first official release of the BeeLang Visual Studio Code extension.
Features
- BeeLang syntax highlighting
- Basic language support
- Improved editing experience for
.beefiles - Easy installation via the provided
.vsixpackage
Installation
- Download
beelang-0.1.0.vsixfrom the release assets. - Open Visual Studio Code.
- Go to Extensions (
Ctrl+Shift+X). - Click the ... menu → Install from VSIX...
- Select
beelang-0.1.0.vsix.
Or install from the command line:
code --install-extension beelang-0.1.0.vsix