Skip to content

What's New in v1.16

"The Batteries Release" — the headline is a real C FFI: you can now call C functions directly and link any C library through wyn.toml, which puts the entire C ecosystem within reach. Plus two Pythonic conveniences: range(a, b, step) and if let.

It's all backward compatible — no source changes are required to upgrade.

Highlights

  • C FFI that worksextern fn with correct int/float/bool/string/void types, and library linking via a new [ffi] section in wyn.toml.
  • range(a, b, step) — Python-style ranges in for loops, including descending.
  • if let — inline conditional binding on Option/Result.

Calling C from Wyn

Declare a C function with extern fn and call it like any other function:

wyn
extern fn sqrt(x: float) -> float;
extern fn pow(base: float, exp: float) -> float;

fn main() {
    println("${sqrt(16.0)}")        // 4.0
    println("${pow(2.0, 10.0)}")    // 1024.0
}

Scalar types (int, float, bool), string, and void all map to the right C types automatically. The C math library is linked by default, so the example above just works.

Linking a C library

To call into any other C library, add an [ffi] section to your wyn.toml:

toml
[ffi]
libs = "curl, z"
lib_dirs = "/usr/local/lib"
include_dirs = "/usr/local/include"

The compiler passes the right -l, -L, and -I flags to the C compiler and links the libraries into your program. libs is a comma- or space-separated list of library names (each becomes -l<name>); lib_dirs and include_dirs are optional search paths. For safety, the compiler rejects any [ffi] value containing shell metacharacters.

This is the first phase of Wyn's ecosystem story — decades of battle-tested C libraries are now reachable. Automatic binding generation and a package-manager experience are on the way.

range(a, b, step)

A Python-style range as a for-loop iterator, alongside the existing a..b operator:

wyn
for i in range(0, 5)      { … }   // 0 1 2 3 4
for i in range(0, 10, 2)  { … }   // 0 2 4 6 8
for i in range(10, 0, -1) { … }   // 10 9 8 … 1  (negative step counts down)

if let

Bind and test a single Option/Result case inline, without a full match:

wyn
fn find(key: string) -> int? { … }

if let Some(v) = find("answer") {
    println("found ${v}")
} else {
    println("missing")
}

It works on any Option or Result, with or without an else branch, and binds the payload in the then-branch.

Upgrading

bash
wyn --version        # 1.16.0

No source changes are required — v1.16.0 is a drop-in upgrade over v1.15.0.

See also

MIT License — v1.16