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 works —
extern fnwith correctint/float/bool/string/voidtypes, and library linking via a new[ffi]section inwyn.toml. range(a, b, step)— Python-style ranges inforloops, including descending.if let— inline conditional binding onOption/Result.
Calling C from Wyn
Declare a C function with extern fn and call it like any other function:
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:
[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:
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:
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
wyn --version # 1.16.0No source changes are required — v1.16.0 is a drop-in upgrade over v1.15.0.
See also
- What's New in v1.15 — the Payloads Release
- What's New in v1.14 — the Polish Release
- Version History