Releases: jamesc/beamtalk
Releases · jamesc/beamtalk
Nightly Build (2026-04-18, 3a897b1a)
v0.3.1
0.3.1 — 2026-03-26
Language
- Actor message timeout configuration syntax — configure per-message timeouts with language-level syntax (BT-1190)
- Rename
trace:/traceCr:toshow:/showCr:on Object — clearer naming for debug output methods (BT-1636) - Fix
^and:=in match arm bodies — non-local returns and assignments inside match arms now compile correctly - Fix
whileTrue:silently drops mutations in value-type context (BT-1609)
Standard Library
- Tracing — new
Tracingstdlib class with Erlang shim for trace context, propagated context across actor boundaries, causal trace linking, and application-level metadata enrichment (BT-1604, BT-1605, BT-1625, BT-1633, BT-1639) - Protocol enhancements — class methods in protocol definitions, REPL support for
Protocol define:declarations, fix protocol-only files not generatingregister_class/0, fix class prefix before doc comments in protocol signatures (BT-1610, BT-1611, BT-1612, BT-1616, BT-1617, BT-1618) performLocally:withArguments:— new class method dispatch primitive that executes in the caller's process, enabling synchronous class method calls without actor messaging (BT-1664)Foo classmethods return user-defined class methods (BT-1635)- Emit class method doc comments in codegen (BT-1634)
- Revert method combinations (
before/afterdaemons) andmigrate:protocol — removed BT-102 and BT-106 pending redesign
Compiler
- Direct-call optimization for sealed class methods — sealed classes now emit direct function calls instead of dynamic dispatch, improving performance (BT-1639)
- Enforce
field:/state:keyword alignment by class kind — the compiler rejectsstate:in value classes andfield:in stateful classes (BT-1663) - Improved lint diagnostics — origin tracing and severity levels in lint messages (BT-1588)
- Surface
protocol register_class/0failures as structured errors (BT-1616)
Runtime
- Actor tracing infrastructure — trace store gen_server with lock-free storage, actor send wrapper telemetry, lifecycle telemetry from compiled actor
init/terminate, lifecycle events (spawn, stop, destroy), aggregate actor stats with min/max duration and class name, outcome/class/duration trace filters, wall-clock timestamps with serialized counter, export_traces for trace snapshots (BT-1601, BT-1602, BT-1603, BT-1620, BT-1621, BT-1622, BT-1627, BT-1628, BT-1629, BT-1632, BT-1638, BT-1640, BT-1641, BT-1642) - Fix
String#asAtomintermittent failures on valid strings (BT-1585)
Tooling
- MCP tracing tools — lean surface for trace inspection, integration fixes, and e2e test coverage (BT-1606, BT-1622)
- BUnit parallel test runner with serial opt-out (BT-1624)
- BUnit stack traces show Beamtalk class names and source line numbers — test failures display
.btsource locations instead of compiled Erlang module names - Improved BUnit failure output — caller-first stack frames and relative file paths
- Parallelize CI test suite (BT-1623)
- Fix MCP lint server reporting zero warnings when CLI finds real issues (BT-1587)
- Fix flaky MCP REPL startup tests (BT-1599)
Documentation
- ADR 0070: Package Namespaces and Dependencies (BT-714)
- Tracing documentation and examples (BT-1607)
Internal
- Add parser tests for class member ordering before fields
- Fix flaky
testGreeting— stop own actor intearDown(BT-1662) - Fix
TranscriptStreamtiming races in getting-started tests (BT-1662) - Fix
trigger_hot_reloadtests failing under cover compilation (BT-1630) - Dependency updates: tungstenite 0.29, tokio-tungstenite 0.29, actions/download-artifact v8
v0.3.0
0.3.0 — 2026-03-21
Language
- Parametric types (generics) — classes can declare type parameters (
Value subclass: Stack(T)), with full type checker substitution, constructor inference, and generic inheritance via superclass type application (ADR 0068) - Protocols —
Protocoldeclarations with class-body syntax, protocol registry with conformance checking, runtime queries (conformsTo:,protocols), variance for protocol-typed parameters, and type parameter bounds (T :: Printable) (ADR 0068) - Union types —
T | Usyntax with exhaustive type checking and provenance tracking - Control flow narrowing —
class =,isKindOf:,isNil, andrespondsTo:narrow types inifTrue:/ifFalse:branches - String is now a subclass of Binary — String inherits Binary's byte-level methods; Binary moved under Collection hierarchy (ADR 0069)
- DynamicSupervisor type parameter —
startChildreturn type narrows based on the supervisor's declared child type
Standard Library
- Protocol — new stdlib class wrapping the runtime protocol registry
- Binary — expanded with instance methods:
size,serialize:,deserialize:,fromIolist:,at:,slice:length:,toList, and more - Stdlib generic annotations added to
Result,Array,Dictionary, andSet
Compiler
- Generic type substitution — type checker resolves type arguments through method calls, field access, and constructor patterns
- Dialyzer spec generation — generic types emit proper
-specattributes; CI validates generated specs - Codegen runtime metadata — generic type information preserved at runtime for reflection
- Union type provenance —
InferredType::Unionunified toVec<InferredType>members with source tracking - Fix false type warnings for generic field defaults
Tooling
- MCP — removed
:modulescommand; purged "module" terminology in favour of "class" throughout - Single-source versioning —
VERSIONfile at repo root with automatic dev suffix from git state - Nightly builds — distribution builds and
install.sh --nightlysupport - MCP load_project — rebuild class indexes after each file load, fixing test fixture resolution (BT-1608)
Documentation
- ADR 0068: Parametric Types and Protocols (updated)
- ADR 0069: Actor Observability and Tracing (BT-1429)
- ADR 0069: Make String a subclass of Binary
- Learning guide 27: Generics and Protocols
Internal
- Fix flaky CI: WebSocket health check with exponential backoff (BT-1598)
- Fix broken streamlinear-cli installation in cloud and devcontainer
- Binary instance method tests and
Binary size:migration (BT-1594) - String method audit verifying Binary inheritance (BT-1595)
v0.2.0
0.2.0 — 2026-03-20
Language
- Three distinct class kinds —
Value subclass:(immutable,field:),Actor subclass:(mutable process,state:),Object subclass:(methods only, no data). Wrong keyword/class-kind combinations are now compile errors (ADR 0067) - Extension methods (
>>) — add methods to sealed classes from outside, with compile-time conflict detection and type metadata (ADR 0066) - Extension type annotations —
:: -> ReturnTypeon>>definitions for gradual type checking initialize:lifecycle hook — Supervisor and DynamicSupervisor support post-start initializationterminate:lifecycle hook — documented and tested actor cleanup on shutdown- Actor process monitoring —
monitor,pid,onExit:for observing actor lifecycle - Non-local return fix —
^in blocks correctly unpacks super/tier2/self-dispatch tuples
Standard Library
78 classes (up from 76), including new and improved:
- Binary —
serialize:,deserialize:,size:,fromIolist:for byte-level operations - Logger — stdlib class wrapping Erlang's OTP logger with
info:,warning:,error:,debug:and compile-time domain metadata inlining - File —
readBinary:,writeBinary:contents:,appendBinary:contents:for binary I/O;lastModified:for file timestamps - Pid —
kill,exit:for forced process termination;isAlivefor liveness checks - System —
uniqueIdfor monotonic ID generation;setEnv:value:,unsetEnv:for environment variables - Time —
nowSfor seconds-precision timestamps - Ets —
exists:,newOrExisting:type:for safer table lifecycle - Subprocess —
dir:parameter for working directory control - Server —
handleInfo:for handling raw BEAM messages in actors - Timer —
spawn_linkvariant for linked timer processes - Supervisor —
withShutdown:for configurable shutdown timeouts - BUnit —
setUpOnce/tearDownOncesuite-level lifecycle hooks;TestCaseconverted to Value subclass with functionalsetUp
Bug fixes in stdlib
String collect:now returns List (was incorrectly returning String)String asStringreturnsselfinstead ofprintStringInteger raisedTo:returns Integer for non-negative integer exponentsHTTPClientworks in compiled test contexts- Erlang FFI charlist return values auto-converted to String
- File path sandbox removed —
Filenow accesses unrestricted paths (ADR 0063)
Compiler
- State threading overhaul — local variable mutations inside blocks,
ifTrue:/ifFalse:branches, and self-sends in assignment RHS now correctly propagate in both Value types and Actors. Coverscollect:,select:,reject:,detect:,flatMap:,do:,doWithKey:,takeWhile:,dropWhile:,groupBy:,partition:,sort:,anySatisfy:,allSatisfy:,each:,inject:into:, andcount: - Cross-file class hierarchy — type checker resolves class kinds and methods across files;
ClassKindpropagation walks ancestor chain - Extension method pipeline — scanner collects
>>definitions across project, emitter generates ETS-dispatch code, type checker reads extension metadata @expect dead_assignment— new suppression annotation for intentional dead assignments- Keyword constructor hashing — long keyword constructor atom names hashed to stay within Erlang's 255-char limit
- Parser — helpful error for unescaped
{in strings (was a crash); stale@expect typetreated as error new/new:moved from Object to Value — Object-kind classes can no longer be instantiated; constructors are Value-only. Sub-subclass instantiation (new/new:/keyword ctors) now works correctly- Lint improvements — warn when Object subclass has only state + getters (suggests Value); block-scoped variable mutation lint for value types; removed false-positive self-capture lint (BT-953)
- Codegen refactoring — decomposed large functions across gen_server dispatch, state threading, method body loops, and register_class; explicit return values replace implicit side-channel fields; unified branch body loops with classify/dispatch pattern
- Performance — cache Pass 1 ASTs to eliminate double-parse in package build; REPL
:loadbuilds class indexes once per batch
Tooling
- Logging and observability (ADR 0064):
beamtalk logsCLI command for workspace log access- JSON log format switching via
Beamtalk logFormat: - Per-class and per-actor debug filtering with
enableDebug: Beamtalk logLevel:replaces deprecatedLogger setLevel:- Actor lifecycle, message dispatch, compilation pipeline, supervisor lifecycle, and MCP tool invocation logging
- SASL reporting routed to workspace file logger
- VS Code output panel with live log streaming
- MCP —
list_classes,search_classes, docssee-alsolinks, WebSocket keepalive, per-diagnostic line numbers inload_project, client reconnect after workspace restart - VS Code — log level picker and show-logs button
- REPL — fixed destructured bindings escaping into persistent scope; REPL codegen extracted from Compilation context
- AGENTS.md — essential patterns, MCP workflow, scaffold templates extracted to external files
Bug Fixes
- Actor self-call state mutations no longer silently lost via
safe_dispatch - Supervisor correctly calls Actor
initializehook on child start ifTrue:/ifFalse:propagate local var mutations in value types and REPL- Class method calls inside blocks in class methods no longer produce codegen error
- Self-cast sends in blocks no longer route through actor mailbox (deadlock fix)
- Logger formatter crashes on
{string, Binary}tuples and unicode — hardened with crash-proof JSON formatter beamtalk run .hostname error when workspace already runningFile absolutePath:returns correct path on Windows/macOS- Dispatch error logging demoted to debug (reduces runtime log noise)
- Scope leak fix when
generate_method_body_with_replyreturns Err in dispatch codegen - Actor method error messages enriched with stacktrace and source location
- Move
initializedispatch tohandle_continueto surface init errors properly - Float literals retain decimal in codegen for strict equality correctness
- BUnit fixture superclass index fix for Value sub-subclass tests