<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Blog on Xo Language</title><link>https://xolang.dev/blog/</link><description>Recent content in Blog on Xo Language</description><generator>Hugo</generator><language>en-US</language><lastBuildDate>Sat, 10 Oct 2026 12:00:00 -0400</lastBuildDate><atom:link href="https://xolang.dev/blog/index.xml" rel="self" type="application/rss+xml"/><item><title>Introducing Xo</title><link>https://xolang.dev/blog/introducing-xo/</link><pubDate>Sat, 10 Oct 2026 12:00:00 -0400</pubDate><guid>https://xolang.dev/blog/introducing-xo/</guid><description>&lt;p&gt;Xo (pronounced &lt;em&gt;ex-oh&lt;/em&gt;) is a small, statically typed language for backends&#10;and web services. It is built for a world where AI agents write much of the&#10;code, and it starts from one observation: agents make the same mistakes&#10;people do, only faster. They ignore an error, dereference a nil, forget a&#10;case, share a map between goroutines, or call the network from a function&#10;that looked pure. Tests catch some of these. Review catches some more. Many&#10;reach production.&lt;/p&gt;</description></item><item><title>Xo v0.9.0</title><link>https://xolang.dev/blog/v0-9-0/</link><pubDate>Sat, 10 Oct 2026 00:00:00 +0000</pubDate><guid>https://xolang.dev/blog/v0-9-0/</guid><description>&lt;p&gt;Spec draft 0.9.&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Module proxies (decision 0126): &lt;code&gt;XO_PROXY&lt;/code&gt; lists proxy URLs, &lt;code&gt;direct&lt;/code&gt;&#10;(git), and &lt;code&gt;off&lt;/code&gt;, with Go&amp;rsquo;s fallback rules (comma after 404/410, pipe&#10;after any error; default &lt;code&gt;direct&lt;/code&gt;), and &lt;code&gt;XO_NOPROXY&lt;/code&gt; patterns go to&#10;git. The read only protocol serves &lt;code&gt;@v/list&lt;/code&gt;, &lt;code&gt;.mod&lt;/code&gt;, &lt;code&gt;.zip&lt;/code&gt;, and&#10;&lt;code&gt;.lock&lt;/code&gt; per module; &lt;code&gt;xo mod proxy serve [--fetch] [&amp;lt;cache dir&amp;gt;]&lt;/code&gt;&#10;serves a module cache and can fill it from git, as a team cache.&#10;Proxied trees are checked against xo.lock exactly as git fetches are.&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Checksum log (decision 0124): with &lt;code&gt;XO_SUMDB=&amp;lt;name&amp;gt;+&amp;lt;id&amp;gt;+&amp;lt;key&amp;gt; [&amp;lt;url&amp;gt;]&lt;/code&gt;, the first fetch of every module version must match the&#10;log&amp;rsquo;s record, be in its signed Merkle tree, and extend every tree the&#10;module cache saw before; otherwise &lt;code&gt;XO1313&lt;/code&gt; and nothing is cached. An&#10;unreachable log or malformed settings is &lt;code&gt;XO1314&lt;/code&gt;; &lt;code&gt;XO_NOSUMDB&lt;/code&gt; keeps&#10;private modules out. The default stays &lt;code&gt;off&lt;/code&gt; (no public log yet).&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Definition hashes (decision 0125, the last step of 0086): &lt;code&gt;xo query hash &amp;lt;name&amp;gt;&lt;/code&gt; prints a content hash per top level definition that&#10;survives renaming locals and changes with what the definition, or one&#10;it calls in the module, computes. &lt;code&gt;xo publish --check&lt;/code&gt; lists the&#10;definitions (private ones too) changed since the last tag, including&#10;those changed only through a helper, next to the API comparison.&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;std/http speaks HTTP/2 over TLS on every backend (decision 0121):&#10;&lt;code&gt;with_tls&lt;/code&gt; servers and &lt;code&gt;https&lt;/code&gt; clients agree on &lt;code&gt;h2&lt;/code&gt; by ALPN, plain&#10;&lt;code&gt;http&lt;/code&gt; stays HTTP/1.1, and nothing in the API changes. Requests of a&#10;connection run at once, each as a task; a fault in a streamed body&#10;resets only its stream. The native backends implement it in C (frames,&#10;HPACK, flow control) with net/http&amp;rsquo;s limits (250 streams, the header&#10;list limit with 431, the rapid reset limit) and its error texts, and&#10;their client keeps HTTP/2 connections for later requests as Go&amp;rsquo;s does.&#10;Over one connection the native server does 87.8k requests per second&#10;in the HTTP benchmark, the Go backend 58.2k&#10;(&lt;code&gt;bench/results/http2-2026-10-10.md&lt;/code&gt;).&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Native test binaries (&lt;code&gt;xo test --no-gc&lt;/code&gt;, decision 0120): property tests&#10;and &lt;code&gt;testing.gen&lt;/code&gt; work, with the Go backend&amp;rsquo;s generated values for a&#10;seed, the same failing case, and the same shrunk input in the report.&#10;A &lt;code&gt;Set&lt;/code&gt; or &lt;code&gt;Map&lt;/code&gt; keyed by a sized integer (&lt;code&gt;Set[Int8]&lt;/code&gt;) now builds&#10;natively. &lt;code&gt;xo test --real&lt;/code&gt; gives native tests real capabilities for&#10;the effects they declare (&lt;code&gt;fs&lt;/code&gt;, &lt;code&gt;fs.read&lt;/code&gt;, &lt;code&gt;fs.write&lt;/code&gt;, &lt;code&gt;net&lt;/code&gt;, &lt;code&gt;clock&lt;/code&gt;,&#10;&lt;code&gt;env&lt;/code&gt;, &lt;code&gt;stdio&lt;/code&gt;, &lt;code&gt;proc&lt;/code&gt;), as on the Go backend.&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Native backends: deferred code that faults no longer skips the rest&#10;of the cleanup. The deferred code registered before it and that of&#10;the blocks around it runs, the last fault is reported, as on the Go&#10;backend (core 3.5, decision 0085 amendment), and a task that caught&#10;such a fault with &lt;code&gt;task.isolate&lt;/code&gt; sees cancellation again (it could&#10;deadlock before).&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;LLVM backend (decision 0119): generated code is compiled for the same&#10;CPU and features as the C runtime (clang&amp;rsquo;s defaults): LSE atomics for&#10;shared reference counts on darwin/arm64, outline atomics (LSE when the&#10;CPU has it) on Linux arm64. HTTP benchmark +3.5 percent.&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Native &lt;code&gt;Mutex&lt;/code&gt; (decision 0118): a writer&amp;rsquo;s release hands the lock to&#10;the readers waiting, so they no longer wake only to park again: a&#10;contended readers and writer load (&lt;code&gt;bench/perf/conc&lt;/code&gt; &lt;code&gt;rwmutex&lt;/code&gt;, new)&#10;went from 967 to 131 ms and from 6.3 to 0.25 s of CPU. Long lived&#10;scopes (the native HTTP server&amp;rsquo;s connections) no longer keep every&#10;finished task until they close, and the native allocator moves freed&#10;blocks between threads, so a server&amp;rsquo;s memory stays flat (28 MB instead&#10;of 295 MB after 300k TLS connections).&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Native HTTPS (decision 0117): full TLS handshakes about 1.6 times as&#10;fast and at half the CPU (9.7k to 15k per second in the HTTP benchmark,&#10;Go backend 17k): X25519 key shares through HACL*, faster P-256&#10;inverses, a spinning lock for Mbed TLS&amp;rsquo;s key store, SHA instructions.&#10;The native server now sends session tickets as Go&amp;rsquo;s does (TLS 1.3&#10;resumption with ECDHE, TLS 1.2 tickets; keys rotate daily), so&#10;returning clients skip the certificate signature. &lt;code&gt;bench/perf/http&lt;/code&gt;&amp;rsquo;s&#10;loadgen has &lt;code&gt;-resume&lt;/code&gt; (&lt;code&gt;RESUME=1&lt;/code&gt; in run.sh).&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;code&gt;xo lsp&lt;/code&gt; (decision 0114): a Language Server Protocol server with&#10;diagnostics and their fixes as quick fixes, hover (signature, doc, or&#10;type), definition (into std too), references, rename, document&#10;symbols, semantic tokens, and formatting. The VS Code extension starts&#10;it; ```xo fences in Markdown are highlighted.&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;VS Code syntax highlighting (decision 0113): &lt;code&gt;editors/vscode/&lt;/code&gt; registers&#10;&lt;code&gt;.xo&lt;/code&gt; files with a TextMate grammar covering spec section 1 (keywords,&#10;contextual words, interpolation, raw and bytes strings, durations, sets,&#10;effects in &lt;code&gt;uses&lt;/code&gt;). Install by symlinking it into &lt;code&gt;~/.vscode/extensions&lt;/code&gt;.&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;code&gt;use c &amp;quot;&amp;lt;header&amp;gt;&amp;quot; [link &amp;quot;&amp;lt;lib&amp;gt;&amp;quot;]... [as name] [uses ...]&lt;/code&gt; on the&#10;native backends (decisions 0093 stage 2 and 0116): bindings generated&#10;from the header with clang (&lt;code&gt;xo bind --c&lt;/code&gt;), scalars, Str, Bytes with a&#10;length, flat structs, and opaque handles at the boundary, the &lt;code&gt;ffi&lt;/code&gt;&#10;effect unless the line narrows it, XO1104/XO1105 for headers and names&#10;that do not bind, XO1201 on the Go backend. Calls are not recorded&#10;yet (native builds do not record).&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Decision 0111: passing one variable, or overlapping places (&lt;code&gt;x&lt;/code&gt; and&#10;&lt;code&gt;x.f&lt;/code&gt;, &lt;code&gt;xs[i]&lt;/code&gt; and &lt;code&gt;xs[j]&lt;/code&gt; unless both indexes are different&#10;literals, a &lt;code&gt;var&lt;/code&gt; receiver and an argument naming it), to two &lt;code&gt;var&lt;/code&gt;&#10;parameters of one call is &lt;code&gt;XO0503&lt;/code&gt; on every backend; the native&#10;backends no longer report XO1201 for it.&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Decision 0112: a value that holds a handle (&lt;code&gt;Mutex&lt;/code&gt;, &lt;code&gt;Atomic&lt;/code&gt;, &lt;code&gt;Chan&lt;/code&gt;,&#10;&lt;code&gt;Task&lt;/code&gt;, &lt;code&gt;Scope&lt;/code&gt;, &lt;code&gt;Listener&lt;/code&gt;, &lt;code&gt;Conn&lt;/code&gt;, &lt;code&gt;task.Group&lt;/code&gt;, the std/http and&#10;std/sql handles, the test fakes) or a function value is not&#10;comparable: &lt;code&gt;==&lt;/code&gt;/&lt;code&gt;!=&lt;/code&gt;, Map keys, Set elements, &lt;code&gt;derive Eq&lt;/code&gt;/&lt;code&gt;Hash&lt;/code&gt;, and&#10;&lt;code&gt;T: Eq&lt;/code&gt;/&lt;code&gt;Hash&lt;/code&gt; arguments are &lt;code&gt;XO0404&lt;/code&gt; with a note naming the field&#10;that holds it; &lt;code&gt;derive Ord&lt;/code&gt; already was. The checker now looks into&#10;struct fields and enum payloads for &lt;code&gt;Eq&lt;/code&gt; (it looked only at type&#10;arguments).&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Native backends (decisions 0107 to 0109): &lt;code&gt;Proc.run&lt;/code&gt;, &lt;code&gt;os.tasks&lt;/code&gt; (a&#10;scope around main and around each test), method values&#10;(&lt;code&gt;let f = x.method&lt;/code&gt;), &lt;code&gt;map_concurrent_until&lt;/code&gt;, base64,&#10;&lt;code&gt;Range.to_list&lt;/code&gt;, &lt;code&gt;Rand.shuffle&lt;/code&gt;, &lt;code&gt;target&lt;/code&gt; (a compile time constant),&#10;and in native test binaries MemFs (every method, &lt;code&gt;fail_next&lt;/code&gt;, case&#10;sensitivity, &lt;code&gt;files&lt;/code&gt;), FakeProc &lt;code&gt;run&lt;/code&gt; and &lt;code&gt;on_run&lt;/code&gt;, &lt;code&gt;os.proc.exit&lt;/code&gt;&#10;inside &lt;code&gt;testing.run_main&lt;/code&gt;, and &lt;code&gt;run_main&lt;/code&gt; of a main that cannot fail.&#10;Fixed natively: a receive arm after an &lt;code&gt;after&lt;/code&gt; arm lost its value; a&#10;&lt;code&gt;?&lt;/code&gt; in a closure printed the function&amp;rsquo;s frame name without&#10;&lt;code&gt;.closure&lt;/code&gt;, and one in a &lt;code&gt;Mutex.with&lt;/code&gt; closure none;&#10;&lt;code&gt;FakeClock.advance&lt;/code&gt; returned before the tasks it woke ran; the&#10;success type of &lt;code&gt;Err(e)?&lt;/code&gt; was XO1201. One binding passed to two &lt;code&gt;var&lt;/code&gt;&#10;parameters is now XO1201 natively (the Go backend shares it, the&#10;native backends copied it).&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;TestCompileProperty (decision 0110): random checker valid programs over&#10;the optional syntax must build on the Go backend and with &lt;code&gt;--no-gc&lt;/code&gt;,&#10;and run alike.&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Fixes from Codex r3: a &lt;code&gt;select&lt;/code&gt; arm that receives without binding the&#10;value no longer generates Go that fails to compile; the &amp;ldquo;propagate with&#10;?&amp;rdquo; fix is offered only where &lt;code&gt;?&lt;/code&gt; can propagate; help notes for XO0205&#10;in closures and for passing &lt;code&gt;TestOs&lt;/code&gt; where &lt;code&gt;Os&lt;/code&gt; is expected.&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Native backends (&lt;code&gt;--no-gc&lt;/code&gt;, LLVM and arm64): interface types as values&#10;(decision 0100): dynamic dispatch, adapters for methods that cannot&#10;fail, error conversion, interface to interface conversion, Display and&#10;Debug of the dynamic value, and &lt;code&gt;==&lt;/code&gt;; &lt;code&gt;x.debug()&lt;/code&gt; on any value.&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Native backends: newtypes (&lt;code&gt;Email(&amp;quot;x&amp;quot;)&lt;/code&gt;, &lt;code&gt;e.0&lt;/code&gt; read and assigned,&#10;&lt;code&gt;Email(p)&lt;/code&gt; patterns, Debug, &lt;code&gt;==&lt;/code&gt;, Map keys) and list patterns&#10;(&lt;code&gt;[]&lt;/code&gt;, &lt;code&gt;[a, .., z]&lt;/code&gt;). Fixed: an or pattern whose alternatives bind the&#10;same name (&lt;code&gt;Leaf(v) | Node(left: v, ..)&lt;/code&gt;) read the first alternative&amp;rsquo;s&#10;binding natively, a stale value when another alternative matched.&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Native backends (decision 0101): Float32, &lt;code&gt;Secret[T]&lt;/code&gt; redacted in every&#10;output path, &lt;code&gt;Buf[T]&lt;/code&gt;, &lt;code&gt;&amp;lt;&lt;/code&gt; on &lt;code&gt;derive Ord&lt;/code&gt; types, &lt;code&gt;Int32.try&lt;/code&gt; and the&#10;other sized &lt;code&gt;try&lt;/code&gt;s, &lt;code&gt;Int.pow&lt;/code&gt;, &lt;code&gt;clamp&lt;/code&gt;, &lt;code&gt;min&lt;/code&gt;/&lt;code&gt;max&lt;/code&gt; on Str, Set union,&#10;intersect, difference, &lt;code&gt;Map.filter&lt;/code&gt;, &lt;code&gt;List.insert&lt;/code&gt;, &lt;code&gt;remove_at&lt;/code&gt;,&#10;&lt;code&gt;indexed()&lt;/code&gt;, &lt;code&gt;xs + ys&lt;/code&gt;, std defaults (&lt;code&gt;crypto.token(r)&lt;/code&gt;,&#10;&lt;code&gt;Chan.new()&lt;/code&gt;), &lt;code&gt;get_or_fault&lt;/code&gt; on any key type, builtin collections&#10;through interfaces, shorthand field patterns. &lt;code&gt;==&lt;/code&gt; on a value holding&#10;a function or runtime handle outside an interface is now XO1201&#10;natively (it failed in code generation). New test&#10;TestGenGoldensNative runs 66 internal/gen goldens on Go, LLVM, and&#10;arm64 and compares them.&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Native backends: &lt;code&gt;std/path&lt;/code&gt; (std/native/path.xo), &lt;code&gt;task.semaphore&lt;/code&gt;,&#10;&lt;code&gt;task.once&lt;/code&gt; (a fault in its function is not stored natively: the next&#10;caller runs it again), and &lt;code&gt;task.map_concurrent&lt;/code&gt;&#10;(std/native/task.xo); Debug text of &lt;code&gt;Result[T, Never]&lt;/code&gt; values. Fixed:&#10;natively, a task whose value is a Result failed its scope when that&#10;value was an &lt;code&gt;Err&lt;/code&gt;; shorthand struct patterns &lt;code&gt;Bag{items}&lt;/code&gt;.&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Native backends (decision 0102): every Fs method and attenuation&#10;(&lt;code&gt;sub&lt;/code&gt;, &lt;code&gt;cwd&lt;/code&gt;, &lt;code&gt;read_only&lt;/code&gt;, &lt;code&gt;write_only&lt;/code&gt;, escapes &lt;code&gt;Denied&lt;/code&gt;),&#10;&lt;code&gt;Stdio.write&lt;/code&gt;, and standard input reads (&lt;code&gt;read_line&lt;/code&gt;, &lt;code&gt;read_all&lt;/code&gt;,&#10;&lt;code&gt;lines&lt;/code&gt;) that a cancellation or a stop request ends with&#10;&lt;code&gt;IoErr.Canceled&lt;/code&gt;. Fixed natively: &lt;code&gt;task.with_timeout&lt;/code&gt; returns&#10;&lt;code&gt;TimedOut&lt;/code&gt; when its closure finishes after the deadline without a&#10;cancellation point, as on the Go backend.&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Native backends: error frames (decision 0104): each &lt;code&gt;?&lt;/code&gt; records the&#10;function, location, and parameters lazily, and main&amp;rsquo;s error report&#10;prints &lt;code&gt; at ...&lt;/code&gt; lines identical to the Go backend&amp;rsquo;s.&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Native Fs and standard input code is compiled into a program only when&#10;it calls them (XO_FS, XO_STDIN; hello world unchanged). Fixed: hybrid&#10;builds (&lt;code&gt;--hybrid&lt;/code&gt;) declared a Bool result&amp;rsquo;s argument size rounded up&#10;(go vet -asmdecl).&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;code&gt;xo test --no-gc&lt;/code&gt;: &lt;code&gt;FakeStdio.set_input&lt;/code&gt; feeds the reads; fixed a hang&#10;after &lt;code&gt;FakeProc.signal_after&lt;/code&gt; fired (the virtual clock stopped moving).&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Native backends: all of &lt;code&gt;std/time&lt;/code&gt; (decision 0094; std/native/time.xo&#10;and std/llrt/xo_time.c, a port of Go&amp;rsquo;s TZif reader and zone lookup):&#10;zones with the same per use embedded data (or &lt;code&gt;--tzdata=system&lt;/code&gt;), civil&#10;time, gaps and overlaps, layouts, strict parsing with the same error&#10;texts and faults; also &lt;code&gt;Duration.from_secs&lt;/code&gt;, &lt;code&gt;scale&lt;/code&gt;, &lt;code&gt;ceil_seconds&lt;/code&gt;,&#10;&lt;code&gt;Time.parse_rfc3339&lt;/code&gt;, and &lt;code&gt;Time.UNIX_EPOCH&lt;/code&gt; as a value. Programs that&#10;do not use std/time do not grow. TestTimeDiff compares about 70,000&#10;lines with the Go backend. Fixed: the arm64 backend failed to assemble&#10;functions over 8192 instructions (&lt;code&gt;tbz&lt;/code&gt; range).&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;HTTPS in std/http on every backend (std.md 4.6, decisions 0105 and&#10;0106): &lt;code&gt;http.tls_cert(cert_pem, key_pem)&lt;/code&gt;, &lt;code&gt;Server.with_tls(certs)&lt;/code&gt;&#10;(SNI picks among the certificates), &lt;code&gt;Client.with_roots(pem)&lt;/code&gt;, and&#10;&lt;code&gt;TlsErr&lt;/code&gt;. The native backends (&lt;code&gt;--no-gc&lt;/code&gt;) speak TLS 1.2 and 1.3 through&#10;Mbed TLS 4.1.1 (vendored in &lt;code&gt;third_party/mbedtls&lt;/code&gt;, built once per&#10;compiler into the user cache, linked only into programs that use&#10;std/http), verify against the system&amp;rsquo;s roots on macOS and Linux, and&#10;report Go&amp;rsquo;s error texts; an &lt;code&gt;https&lt;/code&gt; URL is no longer &lt;code&gt;XO1201&lt;/code&gt; there.&#10;std/http speaks HTTP/1.1 only, also over TLS: the Go backend&amp;rsquo;s client no&#10;longer negotiates HTTP/2. Failed TLS handshakes are not logged.&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;code&gt;bench/perf/http/run.sh&lt;/code&gt;: &lt;code&gt;SCHEME=https&lt;/code&gt; serves the Xo configs over TLS&#10;and &lt;code&gt;NEWCONN=1&lt;/code&gt; opens a connection (and a handshake) per request.&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;</description></item><item><title>Xo v0.7.0</title><link>https://xolang.dev/blog/v0-7-0/</link><pubDate>Fri, 09 Oct 2026 00:00:00 +0000</pubDate><guid>https://xolang.dev/blog/v0-7-0/</guid><description>&lt;p&gt;First tagged release. Spec draft 0.7.&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Language: request scoped arenas by default, &lt;code&gt;use go&lt;/code&gt; packages, two&#10;phase shutdown, &lt;code&gt;Mutex.with_read&lt;/code&gt;, &lt;code&gt;BytesBuilder&lt;/code&gt;, rune and integer&#10;conversions, native contracts and fault unwinding, habit diagnostics&#10;(XO0177), &lt;code&gt;clock.sleep_or_cancel&lt;/code&gt;, cancellable stdin, tuple JSON,&#10;&lt;code&gt;Duration.parse&lt;/code&gt; (decisions 0041 to 0088).&lt;/li&gt;&#10;&lt;li&gt;Backends: Go (default), LLVM, native arm64, &lt;code&gt;--no-gc&lt;/code&gt;, &lt;code&gt;--hybrid&lt;/code&gt;.&lt;/li&gt;&#10;&lt;li&gt;Toolchain: &lt;code&gt;xo version&lt;/code&gt;.&lt;/li&gt;&#10;&lt;li&gt;Planned before 1.0: modules and workspaces (0086), &lt;code&gt;std/time&lt;/code&gt;, native&#10;TLS, and decisions on the Appendix B questions.&lt;/li&gt;&#10;&lt;/ul&gt;</description></item><item><title>Xo v0.8.0</title><link>https://xolang.dev/blog/v0-8-0/</link><pubDate>Fri, 09 Oct 2026 00:00:00 +0000</pubDate><guid>https://xolang.dev/blog/v0-8-0/</guid><description>&lt;p&gt;Spec draft 0.8.&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Modules (decision 0086 steps 1 and 2): &lt;code&gt;require &amp;lt;path&amp;gt; &amp;lt;version&amp;gt;&lt;/code&gt; of Xo&#10;modules, minimal version selection, git fetch into a read only module&#10;cache, &lt;code&gt;xo.lock&lt;/code&gt; hashes verified on every build, &lt;code&gt;xo get&lt;/code&gt;, &lt;code&gt;xo mod tidy&lt;/code&gt;, &lt;code&gt;xo vendor&lt;/code&gt;, &lt;code&gt;xo mod clean&lt;/code&gt;, &lt;code&gt;--offline&lt;/code&gt;, and &lt;code&gt;xo.work&lt;/code&gt;&#10;workspaces (&lt;code&gt;--workspace=off&lt;/code&gt;). Diagnostics XO1301 to XO1308.&lt;/li&gt;&#10;&lt;li&gt;Codex r2 first run failures: &lt;code&gt;XO0175&lt;/code&gt; for several match arms on one&#10;line has a split fix and no longer cascades into a false &lt;code&gt;XO0301&lt;/code&gt;;&#10;&lt;code&gt;.display()&lt;/code&gt; works on every &lt;code&gt;Display&lt;/code&gt; type (derived, std errors,&#10;builtins); a closure that never completes infers &lt;code&gt;Never&lt;/code&gt; instead of&#10;&lt;code&gt;XO0402&lt;/code&gt;.&lt;/li&gt;&#10;&lt;li&gt;Effect ceilings and checked semver (decision 0086 steps 3 and 4):&#10;&lt;code&gt;require &amp;lt;path&amp;gt; &amp;lt;version&amp;gt; uses none&lt;/code&gt; in xo.mod and &lt;code&gt;use &amp;lt;dir&amp;gt; uses ...&lt;/code&gt;&#10;in xo.work (XO1309 at a call above the ceiling), API and effect diffs&#10;from &lt;code&gt;xo get&lt;/code&gt; (and &lt;code&gt;xo get -u&lt;/code&gt;), &lt;code&gt;xo publish [--check]&lt;/code&gt; against the&#10;previous tag (XO1310, XO1311; prints the tag command, never pushes),&#10;&lt;code&gt;xo init&lt;/code&gt;, &lt;code&gt;/vN&lt;/code&gt; major version module paths, and &lt;code&gt;xo serve&lt;/code&gt; noticing a&#10;new or changed xo.work above the directories.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;std/time&lt;/code&gt; (decision 0094, Go backend): zones with per use embedded&#10;data (&lt;code&gt;--tzdata=system&lt;/code&gt;), civil dates and times with explicit daylight&#10;saving gaps and overlaps, layouts with named fields checked at compile&#10;time (XO0420; XO0177 for &lt;code&gt;{yyyy}&lt;/code&gt;, &lt;code&gt;%Y&lt;/code&gt;, &lt;code&gt;2006-01-02&lt;/code&gt; habits).&lt;/li&gt;&#10;&lt;li&gt;Import direction rules (decision 0095): &lt;code&gt;deny &amp;lt;pkg&amp;gt; -&amp;gt; &amp;lt;pkg&amp;gt;, ...&lt;/code&gt;&#10;lines in xo.mod with &lt;code&gt;/...&lt;/code&gt; patterns, checked at every &lt;code&gt;use&lt;/code&gt; line&#10;(new code XO1312; a rule naming no package is XO1301), kept by &lt;code&gt;xo mod tidy&lt;/code&gt;; &lt;code&gt;xo query imports&lt;/code&gt; and &lt;code&gt;xo query deps&lt;/code&gt; list the &lt;code&gt;use&lt;/code&gt; lines&#10;(also in the MCP &lt;code&gt;query&lt;/code&gt; tool).&lt;/li&gt;&#10;&lt;li&gt;std/time error text (std.md 13): &lt;code&gt;ZoneErr&lt;/code&gt; and &lt;code&gt;CivilErr&lt;/code&gt; display as&#10;sentences (&lt;code&gt;unknown time zone &amp;quot;Mars/Olympus&amp;quot;&lt;/code&gt;, &lt;code&gt;2026-03-08T02:30:00 America/New_York does not exist (skipped by a daylight saving change)&lt;/code&gt;) instead of the derived &lt;code&gt;Skipped(at: ...)&lt;/code&gt; form, matching&#10;&lt;code&gt;ParseErr&lt;/code&gt; and &lt;code&gt;LayoutErr&lt;/code&gt;.&lt;/li&gt;&#10;&lt;li&gt;Newtypes (decision 0097, spec audit gap 4): &lt;code&gt;e.0&lt;/code&gt; reads the underlying&#10;value and &lt;code&gt;Email(s)&lt;/code&gt; destructures it in &lt;code&gt;let&lt;/code&gt; and &lt;code&gt;match&lt;/code&gt;.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;xo check --fix&lt;/code&gt; (decision 0096): applies the unambiguous machine fixes&#10;(as &lt;code&gt;xo fix&lt;/code&gt;), reformats, then reports what remains plus an &lt;code&gt;applied&lt;/code&gt;&#10;list; the MCP &lt;code&gt;check&lt;/code&gt; tool takes &lt;code&gt;fix&lt;/code&gt;, and the bench harness agent&#10;loop uses it while still scoring first runs as written and after fix.&lt;/li&gt;&#10;&lt;li&gt;Go backend output (decision 0098): hello world 7.9 to 3.6 MB, Go build&#10;cache growth per program 34 to 2.9 MB, compile memory 286 to 123 MB.&#10;Binaries carry no DWARF or symbol table (&lt;code&gt;XO_GO_DWARF=1&lt;/code&gt; keeps them for&#10;a debugger); programs that do not import std/http do not link net/http.&lt;/li&gt;&#10;&lt;li&gt;Spec audit second pass: &lt;code&gt;x.debug()&lt;/code&gt; works on every value (std.md 1;&#10;was XO0601 on concrete types); new tests for single field positional&#10;variants, &lt;code&gt;Secret&lt;/code&gt; redaction in Debug and log fields, &lt;code&gt;target&lt;/code&gt; at run&#10;time, &lt;code&gt;Stdio.write&lt;/code&gt;, &lt;code&gt;Fs.cwd&lt;/code&gt;, &lt;code&gt;Fs.case_sensitive&lt;/code&gt;, a real &lt;code&gt;Proc.run&lt;/code&gt;,&#10;&lt;code&gt;XO-F005&lt;/code&gt;, &lt;code&gt;xo test --real&lt;/code&gt;, and byte identical rebuilds (spec 12.1 now&#10;says &amp;ldquo;in the same directory&amp;rdquo;).&lt;/li&gt;&#10;&lt;li&gt;Modules in repository subdirectories (decision 0086): a module path&#10;&lt;code&gt;github.com/acme/tools/cli&lt;/code&gt; is the directory &lt;code&gt;cli/&lt;/code&gt; of the repository&#10;&lt;code&gt;github.com/acme/tools&lt;/code&gt;, versioned by tags &lt;code&gt;cli/vX.Y.Z&lt;/code&gt; (as Go);&#10;fetch, MVS, xo.lock, &lt;code&gt;xo vendor&lt;/code&gt;, &lt;code&gt;xo get&lt;/code&gt;, and &lt;code&gt;xo publish [--check]&lt;/code&gt;&#10;(prefixed tag command) handle it; nested modules are left out of a&#10;module&amp;rsquo;s tree and hash.&lt;/li&gt;&#10;&lt;li&gt;Go calls in record and replay (decision 0093 stage 1): &lt;code&gt;--record&lt;/code&gt;&#10;records &lt;code&gt;use go&lt;/code&gt; calls whose arguments and results are values (an&#10;argument hash and the results) and &lt;code&gt;xo replay&lt;/code&gt; answers them without&#10;calling Go; calls with a Go handle or a callback run again and the&#10;replay reports &lt;code&gt;re executed foreign call `&amp;lt;name&amp;gt;` &lt;/code&gt;; pure std&#10;packages and xo.mod &lt;code&gt;replay rerun go &amp;lt;path&amp;gt; [names]&lt;/code&gt; lines are not&#10;recorded. Binding format v5; traces gain &lt;code&gt;&amp;quot;foreign&amp;quot;: 1&lt;/code&gt;, and older&#10;traces still replay (every Go call runs again).&lt;/li&gt;&#10;&lt;li&gt;Release builds (decision 0099): &lt;code&gt;xo build --release&lt;/code&gt; compiles out&#10;&lt;code&gt;requires(debug)&lt;/code&gt; and &lt;code&gt;ensures(debug)&lt;/code&gt; on every backend and reports&#10;XO1308 for workspace overrides; &lt;code&gt;--ci&lt;/code&gt; does not imply it.&lt;/li&gt;&#10;&lt;li&gt;Lazy error frames (decision 0092, Go backend): frames keep copies of&#10;the parameter values and format them, bounded to 64 bytes, only when a&#10;trace is printed. 1,000,000 errors through 5 frames: 0.93 s to 0.10 s&#10;with short parameters, 2.78 s to 0.10 s with 90 byte ones; error output&#10;unchanged. &lt;code&gt;xo build --release --error-args=false&lt;/code&gt; drops the values.&lt;/li&gt;&#10;&lt;/ul&gt;</description></item></channel></rss>