What's New in v1.14
"The Polish Release" — the optional and result types you already use, now with the clean syntax they always deserved, plus a handful of ergonomic fixes that remove the last bits of ceremony from everyday code.
It's all backward compatible — no source changes are required to upgrade.
Highlights
- Clean optional/result return types — write
-> int?,-> string?, and-> Result<int, string>directly. The old mangled names are gone. matchas an expression on anyOption/Result, with any payload type.- Type-inferred default arguments —
fn greet(who = "world"), no annotation. println(array)prints the real values.- Negative string indexing —
s[-1]is the last character. - if/else where all branches return no longer needs a trailing return.
Clean Optional and Result Return Types
You can now annotate a function's return type with the sugar directly — int?, string?, or Result<int, string> — instead of a mangled type name:
fn find(t: int) -> int? {
if t > 0 { return Some(t) }
return None()
}
fn parse(s: string) -> Result<int, string> {
if s == "" { return Err("empty") }
return Ok(42)
}Some/None/Ok/Err in the body lower to the right type automatically, and the signature reads exactly the way you'd write it in prose.
match as an Expression
match on an Option or Result now produces a value in expression position, for any payload type — so you can fold both arms into a single binding:
fn parse(s: string) -> Result<int, string> {
if s == "" { return Err("empty") }
return Ok(42)
}
var r = parse("42")
var msg = match r {
Ok(v) => v.to_string(),
Err(e) => e,
}
println(msg) // 42Options work the same way:
var opt: string? = Some("Wyn")
var name = match opt {
Some(v) => v,
None => "anonymous",
}
println(name) // WynType-Inferred Default Arguments
The type of a default parameter is inferred from its value, so the annotation is optional:
fn greet(who = "world") -> string {
return "Hello, ${who}!"
}
fn dial(host = "localhost", port = 8080) {
println("Connecting to ${host}:${port}")
}
greet() // Hello, world!
greet("Wyn") // Hello, Wyn!
dial() // Connecting to localhost:8080
dial("0.0.0.0") // Connecting to 0.0.0.0:8080Typed defaults (who: string = "world") still work if you prefer to be explicit.
Everyday Ergonomics
A few smaller fixes remove common friction:
// println prints an array's real values
var nums = [1, 2, 3]
println(nums) // [1, 2, 3]
// negative string indexing
var s = "hello"
println(s[-1]) // o — last character
// if/else where every branch returns needs no trailing return
fn classify(n: int) -> string {
if n > 0 {
return "positive"
} else {
return "non-positive"
}
}Upgrading
wyn --version # 1.14.0No source changes are required — v1.14.0 is a drop-in upgrade over v1.13.0. If you were writing mangled return types like -> OptionInt or -> ResultInt, you can now replace them with -> int? and -> Result<int, string>, though the old forms still compile.
See also
- What's New in v1.13 — the Pythonic Release
- What's New in v1.12 — the Hardening Release
- Error Handling — Result and Option in depth
- Version History