Sabre v0.1.1

Written by Reuben RoesslerSat Mar 21 2026

Rename Notice

Since v0.3.1-stable Talos has been renamed to Sabre. It is recommended to use any version since the rename both to align with current documentation and for newer features and bug fixes.

If you are currently using an old Talos version, please upgrade to Sabre using the appropriate installer script:

curl -fsSL https://sabre.rroessler.io/install.sh | bash

Otherwise if you have retroactively installed a Talos version after Sabre was released, you can use the following to upgrade:

Terminal
talos upgrade

Class Declarations

With the introduction of Sabre v0.1.1, comes the implementation of class declarations. Classes are the templates for defining nominal objects. They are constructed similarly to function expressions, where their body is contains fields that are bound as they are declared.

// Defining a 2D Position Class.
class Position(a_x?: Number, b_x?: Number) {
    // - PROPERTIES - //

    private let m_x = a_x ?? 0;
    private let m_y = a_y ?? 0;

    // - PUBLIC METHODS - //

    public let x = fn: Number => Self.m_x;
    public let y = fn: Number => Self.m_y;
};

// Instantiating differing positions.
let start = Position();
let end = Position(5, 8);

Classes can also inherit from other class declarations.

// Define a base class.
class Animal(a_kind: String, a_sound: String = "...") {
    // - PROPERTIES - //

    public let kind = a_kind;
    public let noise = a_sound;
};

// Let's prepare a variety of derived classes.
class Cat => Animal("Cat", "Meow") {};
class Dog => Animal("Dog", "Woof") {};
class Rat => Animal("Rat", "Squeak") {};
class Fish => Animal("Fish") {};

// Prepare a polymorphic value to test outputs.
let listen = fn (animal: Animal) => Debug.println("{0}: '{1}'".fmt(animal.kind, animal.noise));

// Test all the variadic values now.
listen(Cat());
listen(Dog());
listen(Rat());
listen(Fish());

For more information regarding specifics for using classes, see the class fundamentals section.

Compile-Time Attributes

Alongside the release of improved support for objects in Sabre comes compile-time attributes. Similar to annotations in other languages (eg: Java, Dart), Sabre allows a limited set of tools to provide the runtime with metadata for variable declarations.

Deprecation Annotations

Variable declarations can now be noted as deprecated and any usage of these variables will be hinted as such (see the linting command for restricting deprecation usage).

// Annotating a variable as being deprecated.
#[Deprecated "This value is deprecated and will be removed in a future release"]
let value = ...;

// In a code-editor with a compatible Sabre language-server, any usage of `value` will now be noted as deprecated.
Debug.println(value); 

Limited Operator Hooks

In conjunction with the upcoming use statement, attributes also allow defining custom operators for classes and objects.

// Suppose we have a class that contains a disposable resource.
class Resource {
    // We can then define a custom disposable handler.
    #[Operator.dispose]
    private let m_dispose = fn { ... };
};

// And when instantiating resources, they can be made disposable.
use resource = Resource();

Explicit Resource Management

As briefly explained above, this release of Sabre implements the use statement for explicit resource management. It works similarly to the using statement in TypeScript, where values that declare a disposal callback will be automatically destroyed at the end of the scoped lifetime.

// Let's define a resource generator.
let scoped = fn (label: String): Any {
    // Show when the resource is created.
    Debug.println("Created '{0}'".fmt(label));

    // An anonymous resource (see below note).
    let resource = {};

    // Attaching a disposal callback to the resource directly.
    #[Operator.dispose resource]
    let callback = fn { Debug.println("Disposed '{0}'".fmt(label)); };

    // Return the constructed resource.
    return resource;
};

use a = scoped("A");
use b = scoped("B");

{
    use c = scoped("C");
    use d = scoped("D");
}

use e = scoped("E");

For more information, see the explicit resource management usage page.

Note:

Currently, there are no typings available for explicit resources. These are planned to be added in the future with a Disposable interface type and additional library support.

Upcoming Work

With the foundations of these big features will come some further improvements to the language server and the implementation of decorators.


Bug Fixes

Package / sabre

  • Moved: Some standard library crates have been renamed to simplify imports. This is primarly for performance (eg: smaller naming = faster parsing), but aimed not to remove readability.
  • Moved: The core project structure around a little bit. Previously, the runtime was written under the naming convention sabre::forge, and was exposed using a CMake interface library as sabre::sabre. Now the runtime has been moved solely into a standalone library as sabre::sabre. To then expose crate dylib:* module registrations with this standalone library, the identifier sabre::crates is now used.

Package / vscode

  • Fixed: Executable lookup now attempts to firstly find sabre within the $HOME/.sabre directory.

Toolkit / sabre run

  • Added: Implemented class statements. This includes: type-checking, instantiation, super-constructors, and interfaces.
  • Added: Integrated the NO_PROGRESS environment variable. For more details see the standards website.
  • Added: Implemented the Deprecated attribute hook. This allows marking variables as deprecated (exposed via the type-system).
  • Added: Implemented the Operator attribute hook foundations. This allows setting limited custom operators to objects (eg: call, dispose and iterator).
  • Added: Completed explicit resource management foundations. This includes: use statements, and disposal attributes.
  • Began: Started the foundations for implementing a debugger. The core principle behind doing so is limited bytecode opcodes to a 7-bit value and using the most-significant to indicate that a breakpoint as been set.

Toolkit / sabre upgrade

  • Fixed: Simplified the uninstall process on Windows. Previously it used a scheduled-task, however this has been replaced with a delayed rmdir command invoked through a hidden separate process using the start command.

Crate / sabre:ffi

  • Added: Prepared stub typings for a future FFI implementation.

Crate / sabre:gc

  • Moved: Renamed the garbage collection module from sabre:garbage to sabre:gc.

Crate / sabre:mem

  • Moved: Renamed the virtual memory module from sabre:memory to sabre:mem.

Crate / sabre:uuid

  • Added: Exposed all UUID versions 1, 3, 4, 5, 6 and 7, alongside available namespace seeds.