Known Limitations
Wyn is honest about what works and what doesn't. Every item below was re-run against the published v1.21.0 binary rather than carried forward from the last release. Two entries moved to "no longer limitations" as a result, and five are new - four of those found by re-running the list rather than by a bug report, which is the argument for re-running it.
Runtime
spawnon a closure returns the wrong answer, silently. A closure called directly returns its value; the same closurespawned returns0.wyn checkpasses, the build succeeds, and the process exits 0:wynvar n = 5 g = (() => n * 2) println(g()) // 10 f = spawn (() => n * 2) println(await f) // 0 <-- wrongspawnneeds a function pointer, and a closure's captured environment is not carried across. Until this is fixed, pass captured values as explicit parameters to a named function and spawn that. This is the most serious item on this page because nothing warns you.parallel { }overlaps only two CPU-bound branches. Two branches offib(35)insideparallel { }finish in the time of one; three or four take two dispatch rounds. Fourspawns plusawait_allon the same work finish in one round. Usespawn+await_allwhen you need dependable overlap of more than two CPU-bound branches.Recursive spawn -
spawninside recursive functions works reliably up to ~28K outstanding tasks (fib(22)verified on v1.21.0). Beyond that, the thread pool can deadlock. Use sequential recursion for deep trees,spawnfor parallel leaf work..len()is O(n) on someStringBuilderresults. Strings normally carry a cached length in the RC header, so.len()is O(1) - about 1.7ns regardless of length. SomeStringBuilder.to_string()results arrive without the cache and fall back to a scan: ~2.5μs per call on a 100,000-character string. Hoist.len()out of the loop if you are calling it repeatedly on a builder result.string.len()returns bytes - UTF-8 byte count, not character count."héllo".len()is 6 and"日本語".len()is 9.Math.checked_add()panics, it does not return aResult. It is a guard against silently wrapping, not a recoverable check:Math.checked_add(9223372036854775807, 1)aborts withpanic: integer overflow in checked_add(...).println(v)on a struct with a nested-struct or array field fails to build. It passeswyn checkand then the C compiler rejects the generatedprintf. Structs whose fields are all scalars or strings print fine. Workaround: interpolate insteadprintln("${v}")handles nested structs, arrays and floats correctly:
wynstruct Point { x: int, y: float } struct Box { label: string, p: Point, tags: [int] } b = Box { label: "hi", p: Point { x: 1, y: 2.5 }, tags: [1, 2, 3] } println("${b}") // Box { label: "hi", p: Point { x: 1, y: 2.5 }, tags: [1, 2, 3] } println(b) // check passes, build failsUnknown methods on a builtin namespace pass
wyn checkand fail to build.Time.millis()type-checks clean and then fails in the C compiler withcall to undeclared function 'Time_millis'. The real name isDateTime.millis(). It fails loudly at build time rather than producing a wrong answer, but it is a check-passes/build-fails hole and it is filed as one.
No Longer Limitations
Integer overflow - silent wrap-around.As of v1.21.0, wrapping is defined. Wyn compiles with-fwrapv, so signed integer overflow wraps two's complement and is guaranteed to:9223372036854775807 + 1is-9223372036854775808, every time, at every optimisation level. Previously the optimiser was entitled to assume overflow could not happen, which is how wrapping code turns into deleted comparisons. It costs nothing measurable - fib(35) is unchanged. UseMath.checked_add()if you want the overflow to abort instead.Sort performance - slower than Go.Re-measured on v1.21.0 with both sides optimised:[int].sort()does 1M ints in 73ms against Go'ssort.Intsat 83ms, and 100K in 6.3ms against 7.0ms. The old figures (124ms vs 101ms) compared a Wyn dev build againstgo build, which optimises by default. A dev build really does take 110ms, so use--releasefor anything you intend to time.
Compile Time
- Compile speed -
wyn buildtakes ~356ms (dev) or ~1.18s (release) for hello world, and ~505ms / 1.32s at 5,000 lines.wyn checkalone is 12ms. The bottleneck is the C compiler (clang/gcc), not Wyn's codegen. Go's purpose-built compiler is faster (go buildhello world, forcing a real link: 189ms).
Platform Notes
- Windows cross-compilation - not yet supported from macOS. Linux x64/ARM64 work.
- Regex shorthand classes
\d,\w,\sare unsupported on every platform, and fail silently. The built-in NFA engine treats\das a literald, soRegex.replace(s, "\\d+", "N")rewrites the letters and leaves the digits. Use[0-9],[A-Za-z0-9_]and[ \t\n], which work. Also unsupported: backreferences, lookaround, and capture-group extraction -Regex.matchreturns a plainbool, there is no match object and no.group(n). Everything else works:., classes,*,+,?,{n},{n,m}, alternation, and^/$. Regex.find_allandRegex.splitreturn a newline-joined string, not an array - as doesDb.query(rows by\n, columns by|). Iterate with.trim().split("\n").- Mobile -
system()/popen()return stubs on iOS/Android. - WASM - not yet supported. Runtime has POSIX dependencies that need
#ifdefguards.
See Also
- FAQ - common questions
- Benchmarks - performance numbers
- Version History - all releases