Anton Zhiyanov

Anton Zhiyanov

@antonz.org

Maintainer at https://github.com/nalgeon. Author at https://antonz.org

344 followers19 following209 posts

People running leading AI labs are not fascists, but they are dangerous psychopaths. Their words are mostly noise, but their actions clearly show that they don't care about society in the slightest. We have yet to see the real consequences of this in the coming years.

Given the slop madness happening around, I think I'll switch back to small-scope projects with minimal or no AI usage. A perfect example so far is Be — a 150-line test assertions package in Go. github.com/nalgeon/be

You may have already heard, but the core SQLite team is working on Vec1 — native vector search (ANN) in SQLite. It supports Euclidean (L2) and cosine distances, and uses SIMD for fast vector operations. Vec1 is already feature-complete, but still needs some optimizations. sqlite.org/vec1

This esteemed function in Go's standard library reads the mantissa and exponent from a string and returns seven individual values. I guess someone really hated structs, huh 🫠

Since no one is defending the code author, I guess I'll do it myself :) I haven't actually benchmarked it, but in this case, returning seven values might be justified — if they're passed to the caller through registers instead of the stack. I doubt the author really avoided structs for no reason.

This Go expression is a bit unconventional, but it's completely valid: error.Error(errors.ErrUnsupported) "errors.ErrUnsupported" is a real, though less well-known, error value defined in the errors package. "error" is a real interface type, and "Error" is its method.

Since you can call any method like a regular function, these two calls are equivalent: var err = errors․New("oops") err.Error() // "oops" error.Error(err) // "oops" So error.Error(errors.ErrUnsupported) is just "unsupported operation" 🤓

I have no idea why developers hate examples so much. Sometimes, I'll see a Go proposal discussion with 50 comments where people argue back and forth, but no one gives a single example about what they're talking about. These discussions go nowhere because no one really knows what the others mean.

One of Solod's strengths is its zero-overhead C interop. So I took a break from working on the standard library and made a tool that generates Solod bindings for any C library from its headers. To get started, I also created bindings for some popular C libraries like Raylib, Sodium, and SQLite.

I compiled a Solod program that imports 30 stdlib packages to WebAssembly and did the same with Go and TinyGo. Solod's binary is 2x smaller than TinyGo's and 16x smaller than Go's 😎 All three binaries are fully self-contained (WASIp1).

Running the full Solod stdlib test suite takes 5 seconds (Clang on macOS). It's not as fast as a Go test suite of roughly the same size, but it's still fast enough to provide useful feedback while making changes.

Enabling the address and undefined-behavior sanitizers increases the execution time to 15 seconds, so I usually run them only after everything else is working properly. The slowest ones are GCC container runs with sanitizers or the analyzer. They take 30 to 40 seconds 🫠

I expect the "javafication" of the Go ecosystem to continue with the addition of generic methods in Go 1.27. We probably won't see unnecessary generic abstractions in the standard library, but plenty of third-party code will gladly take advantage of this wonderful opportunity.

Everyone is creating a new programming language these days, often one that's "like Go but with more features" or "like Rust but simpler". Solod, a systems language for C and Go developers, might look like one of those languages. But it takes a different approach.

Solod is literally a subset of Go. It reuses much of Go's existing tooling, including syntax highlighting, LSP, linters, and the package management system. Solod also reuses a lot of Go's stdlib code, with minimal changes to support manual memory management.

Finally, Solod combines this approach with zero-runtime implementation and source-level C interop. Solod relies heavily on Go, and I see that as a strength, not a weakness. Reusing Go's proven tools and stdlib makes Solod more reliable and easier to work with. Relying on Go is a good choice.

Cryptography is one of Go's underrated strengths. The standard library includes many cryptographic algorithms. They're all well-written, well-documented, reasonably concise, and thoroughly audited. Some of them are also very fast!

For example, Go uses platform-specific assembly code for the block step of SHA-256 hashing. My Solod implementation is 10% slower, even with Arm SHA-2 CPU intrinsics. If I use only pure Solod code (just C), it's 7x slower. Go's cryptography is exceptionally well done.

I'm starting to port Go's hashing packages to Solod (a subset of Go that translates to C). At first, I thought about porting MD5, but who actually uses it anymore? So I went with SHA-2 instead.

When I stopped writing interactive release notes for Go, I immediately started making them for Solod, the language I'm working on. I guess I just can't stop writing interactive notes 🤔

By the way, you can easily write blog posts with interactive code examples too. Codapi, the widget and engine I use to run the code, is open source, and the cloud version is free for individual authors.

Adding concurrency to Solod (a subset of Go that translates to C) felt great. But my favorite feature in the upcoming release is preventing the most common kind of dangling pointer: returning a pointer to a local variable from a function.

It's especially important to catch this, because it's perfectly valid in Go — but not in Solod, which has manual memory management. You can use a memory-unsafe language and still have some nice safety features.

Go has 18 built-in functions (since Go 1.21; there were 15 before that). Personally, I use make, append and len all the time. I never use complex/real/imag or print/println. Everything else falls in between. How about you?

I've put together my own crazy language ranking based on the number of sandbox runs in the Codapi playgrounds. As you can see, Lua is number one, Odin is more popular than C#, and Zig is more popular than C — which obviously doesn't quite reflect the reality 😅

The entire Solod language implementation is under 5,000 lines of Go code, plus 700 lines of C built-ins and another 700 lines for tooling. This is only possible because Go's stdlib offers a great lexer and parser, along with a ready-made analysis package in x/tools.

I don't like the functional options pattern in Go, and I'm pretty disappointed that it ended up in the standard library with the new json/v2 package. An honest, plain Options struct is much better.

You might not remember, but one of the reasons Go was appreciated in the early 2010s was that it came with great tooling right out of the box, specifically for testing and benchmarking. Now Solod (a subset of Go that translates to C) is getting a testing tool too!

Solod (a subset of Go that translates to C) is getting a concurrency model. Instead of Go's M:N goroutine scheduler, it uses an M:N thread worker pool with a task queue. Much simpler, but still pretty efficient.

Big day today! Solod (a subset of Go that translates to C) now comes with a networking package. It's pretty basic, but it's still an important step.

As you probably know, UUIDs — v4 and v7 — are finally coming to the Go standard library this summer! I decided to port them to Solod (a subset of Go that translates to C) right away. I also added the Version method, which the Go team chose to leave out.

Solod (a subset of Go that translates to C) now has a freestanding mode. Many standard library packages work fine without needing libc: bytes, strings, slices, maps, mem, math/bits, and utf8. Even the time package mostly works!