0.6.0 10-01-2026

This release brings a lot of useful tools to write buzz code (LSP, formatter and DAP support) along with Windows support.

TIP

This release builds with zig 0.17.0. We will only use tagged version of zig from now on.

Added

Changed

  • buzz binary now uses subcommands for tools and direct paths for execution
    • buzz <script.buzz> runs a standalone script
    • buzz -t <script.buzz> becomes buzz test <script.buzz>
    • buzz -f <script.buzz> becomes buzz format <script.buzz>
    • buzz <directory> runs src/main.buzz from a buzz package directory
    • buzz init and buzz fetch manage package scaffolding and dependencies
    • buzz will start the REPL
  • Extern libraries now must expose only one function which will be called by the compiler to lookup the functions of the library
  • int are now i48 instead of i32 (#306open in new window. )If you're wondering why, it's because all buzz values live in a NaN boxed f64 and the maximum bits available for an integer in there is 48. However, C ABI does not understand i48 so we're still stuck with i32 in FFI for now.
  • main signature can omit args argument
  • Maximum number of enum cases is now 16 777 215 instead of 255
  • pattern.matchAgainst returns now a list of obj{ start: int, end: int, capture: str } and matchAllAgainst a list of those lists
  • Tuples no longer require free form identifier to access their properties: tuple.@"0" can now be tuple.0
  • as? now warns when the cast target is already optional, and as! warns when used with an optional target
  • Removed map.next

Imports

  • Import don't rely on searchers any more, instead the import path provides a deterministic way of finding the imported script
    • buzz:<name> will look for a buzz's standard library <name>
    • pkg:<name>/path/to/<script.buzz> will look for the script under vendors/<name>/src/path/to/<script.buzz>
  • Selective import erases the imported namespace: import print from "buzz:std"; ... print("hello world");
  • Common part of imported namespace gets erased: if imported file as namespace a\b\c and importing script has namespace a\b, only c\ remains

Internal

  • JIT compiler works in a separate thread
  • Better JIT thresholds based of functions/hotspots complexity scores
  • The standard librairies are now statically loaded which gives a small speed boost
  • Build option -Dshow_perf now shows detailed rundown of the time spent in each component of buzz

0.5.0 (01-24-2025)

Major syntax changes

  • Types are now specified after the identifier + : (#310open in new window. )This includes:
    • Variable declarations
    • Function argument definitions
    • Catch clauses
    • if (...: type as ...)
  • Arrow function use => instead of ->
  • Comments and docblocks must now be prefixed by // and /// instead of | and ||
  • Bitwise or operator is | instead of \
  • Function type now use fun keyword instead of Function
  • If a function type has multiple error types, they must be put in parenthesis
  • Namespace can now be multiple \ separated identifiers
  • Qualified name now use \ separator instead of .
  • The float type is renamed to double (#311open in new window)
  • Enum type is declared between <> rather than ()
  • Protocol list object is conforming to is declared between <> rather than ()
  • const keyword is renamed to final (#318open in new window)

Added

  • Immutability by default (#139open in new window)
    • All non-scalar values are immutable by default
    • Mutability can be specified in types and for values with the mut keyword
    • Object methods that mutate this must be prefixed by mut
    • FFI data are considered mutable
  • Compile will warn about variable declared with var but never assigned
  • Object can have final properties (#13open in new window)
  • rg.subsetOf, rg.intersect, rg.union
  • Tuples (#298open in new window: )syntaxic sugar over anonymous objects:
final tuple = .{ "john", "james" };

tuple.@"0" == "john";
  • Checked subscript access to list and strings (gives null when index is out of bound) (#304open in new window😃
var list = [1, 2, 3];

list[?10] == null;

"hello"[?20] == null;

Modified

  • Enum can now have rg, ud, void, pat as value type
  • Anonymous object can also omit property name when initial value is a named variable
  • Mir was updated to 1.0 (#300open in new window)

Fixed

  • Type checking was not done on object instance property assignments
  • Http client could not be collected because it kept connection opened to previous requests' domains
  • Fixed an issue where a JIT compiled function making a lot of function calls would stack overflow

Internal

  • Properties are now retrieved with an index rather than a hashmap lookup (#90open in new window )which gives a nice performance boost of about 40% on some benches

0.4.0 (05-16-2024)

Added

object Person {
    str name,
    str lastName,
}

const name = "Joe";
const lastName = "Doe";

before:

const person = Person {
    name: name,
    lastName: lastName,
};

after:

const person = Person {
    name,
    lastName,
};
var value = from {
    | ...

    out result;
}
  • recursive_call_limit build option limit recursive calls
  • Compiler will warn about code after a return statement
  • Compiler will warn about unreferenced imports (#272open in new window)
  • namespace (#271open in new window: )if a script exports at least one symbol, it has to define a namespace for the script with namespace mynamespace
    • By default, imported symbols from another script will be under libprefix.XXXX
    • When importing something, you can still redefine its namespace prefix with import "..." as mynewnamespace or remove it altogether with import "..." _
  • Ranges are now an actual buzz value (#170open in new window)
    • new rg type
    • myrange.toList() transforms a range into a list of integers
    • myrange.low and myrange.high to get a range bounds
    • works with foreach
  • list.fill
  • std.panic will panic and print current stack trace
  • Loop can have labels that you can break or continue to (#199open in new window)

Changed

  • Map type notation has changed from {K, V} to {K: V}. Similarly map expression with specified typed went from {<K, V>, ...} to {<K: V>, ...} (#253open in new window)
  • File.readLine, File.readAll, Socket.readLine, Socket.readAll have now an optional maxSize argument
  • Empty list and map without a specified type resolve to [any]/{any: any} unless the variable declaration context provides the type (#86open in new window)
  • Function yield type is now prefixed with *>: fun willYield() > T > Y? becomes fun willYield() > T *> Y? (#257open in new window)
  • Temporarily disabled --tree and --fmt. The AST has been completely reworked and those feature will take some work to come back.
  • math.random removed in favor of std.random

Fixed

  • A bunch of crash after reported error. buzz tries to hit a maximum of syntax/compile errors by continuing after an error has been reported. This can lead to unexpected state and crash.
  • Trying to resolve a global when only its prefix was provided would result in infinite recursion
  • Forbid use of yield/resume/resolve in the global scope
  • Would break on unfinished char literal

0.3.0 (10-14-2023)

Added

  • FFI (#109open in new window)
    • Uses MIR to generate wrappers around imported functions and to generate getters and setters to struct fields
    • New zdef statement to declare and bind foreign functions and struct using zig code
    • New ffi std lib
    • When you need a pointer to something you can use the Buffer std lib object. Added:
      • Buffer.writeZ, Buffer.readZ, Buffer.writeStruct, Buffer.readStruct
      • Buffer.ptr, Buffer.len
  • New (fancy) error reporter (#153open in new window)
  • Errors have now an associated code
  • os.sleep
  • First class types (#21open in new window)
    • Type can be passed around as values like so: <str>
    • New typeof operator returns type of any value: typeof "hello" -> <str>
  • Delimiters for non-standard identifiers (#138open in new window)
  • Collectors (http([#2): s://github.com/buzz-language/buzz/issues/2): )if an object has a fun collect() > void method, it will be called before an instance of this object is collected by the garbage collector
  • Helpers around ud
    • std.toUd, returns userdata from an int or float
    • bz_valueToObjUserData
    • bz_getUserDataPtr
    • Buffer.readUserData, Buffer.writeUserData
  • std.serialize takes any buzz value and return a serializable version of it (objects become maps, etc.) provided the data is has no circular reference and does not contain not serializable values (functions, fibers, etc.)
  • UTF8 helpers: str.utf8Len, str.utf8Codepoints, str.utf8Valid (#39open in new window)
  • New integer literal for single chars: 'A' == 65 (#172open in new window)
  • Compiler will warn you when a local or global is never used or when an expression value is discarded. To silence those warnings you can use the _ = <expression> or name the local/global _.
  • std.currentFiber, fiber.isMain (#162open in new window)
  • map.sort, map.forEach, map.map, map.filter, map.reduce, map.diff, map.intersect, map.clone (#110open in new window)
  • list.clone (#110open in new window)
  • Number literals can embed _: 1_000_000.300_245 (#163open in new window)
  • Type can be inferred when declaring a variable/constant with the var or const keyword: var something = "hello" (#194open in new window)
  • Objects can have generic types (#82open in new window)
  • Draft of the testing std lib (#129open in new window)
  • File.isTTY
  • fs.exists
  • Functions annotated with a comment of the form || @hot will always be JIT compiled

Changed

  • json lib is renamed serialize
  • Json now returns a Boxed object (which can be reused in other contexts than JSON)
  • Identifiers can now have _ since pattern delimiters have changed
  • Changed pattern delimiters (#165open in new window)
  • list.append does not return the appended value anymore
  • Generic types syntax changed from myFunction(<K,V>, ...) to myFunction::<K,V>(...)
  • Nullable object fields and nullable variables have a null initial value if none is provided
  • Migrated to pcre2 which is now a submodule built by build.zig
  • Mimalloc is now a submodule built by build.zig

Fixed

  • Some bugs any
  • Runtime error stack trace was wrong
  • Local name checking failed in some instances
  • Compiler would not force you to give variables an initial value
  • Compiler would crash after raising some errors
  • Float operation were sometimes wrong
  • Catch clause were sometimes not reached in a JIT compiled function
  • Stacktraces of errors reported from within a fiber were wrong
  • catch (any error) was not considered as catching all possible errors by the compiler
  • Full GC sweep were never triggered

0.2.0 (07-26-2023)

Added

Changed

  • Main function signature must either be fun main([str] args) > void or fun main([str] args) > int, plus any required errors
  • Numbers are splitted in two types: int (32 bits integers) and float (64 bits floating points)
  • Some performance related changes
    • VM uses tail calls to dispatch opcode instead of a big switch
    • More specialized opcodes to avoid checking types at runtime
    • Some minor things...
  • Key can be omitted in foreach statements
  • buzz wil now search a library in a list of common directories
  • export can prefix declarations

Fixed

Too many to count...

0.1.0 (11-18-2022)

  • static type system
  • null safety
  • "error safety": much like zig, function signatures must specify which errors can be raised and error must be handled
  • objects (struct-like, no inheritance)
  • anonymous objects
  • protocols
  • enums
  • lists and maps
  • fibers (coroutines)
  • userdata (pointer to foreign data wrapped in a buzz value)
  • first-class citizen functions
  • arrow functions
  • generics
  • pcre regex
  • zic/c interop
  • syntax highlighting via vs code extension or by using the TextMate grammar file
  • minimal std lib: buffer, fs, io, os, math, gc, debug
Last Updated:
Contributors: Benoit Giannangeli