Skip to content

ponyc

pony-lint: Codifying the Style Guide

A couple months ago I wrote about teaching Claude to write Pony. The shorthand version: treat the LLM like a junior developer with no memory, build up a CLAUDE.md, refine it as you find where Claude falls short. The CLAUDE.md got Claude most of the way there.

The piece it never quite covered was the style guide. There’s one for the projects under the ponylang GitHub org. It has rules for indentation, line length, naming, where blank lines go. Claude would write code that compiled and worked but didn’t follow the rules. Indentation that should have been two spaces would land on three. A type name would pick up an underscore. A function that belonged on three lines would end up jammed onto one. Stray trailing whitespace. Each one I’d correct. And correct it again. And again.

pony-lsp: An Actor and a Callback

Embed You a ponyc for Great Good introduced libponyc-standalone, a static compiler library you can link your tools against, and a Pony wrapper called pony-ast that exposes the compiler as a callable function. This post is about the Pony language server we built on top of it.

A quick disclaimer before I get going. Almost none of pony-lsp is my work. Matthias Wahl built it from scratch. He wrote the actor architecture, the message dispatch, and the original feature set. He also wrote pony-ast. Orien Madgwick has been pushing it forward; most of the new features over the past several months are his. My contribution is mostly fixing things that broke when I imported the project into ponyc, plus a small feature here and there. The clever stuff is theirs.

Embed You a ponyc for Great Good

The ponyc command you run every day is a main() function with a terminal-width detector glued to it. The actual compiler is a library called libponyc. ponyc is a wrapper around that library, and the wrapper is 149 lines of C.

That’s the setup for this post. The Pony compiler is a library and you can link against it. And because you can link against it, you can build your own tools. And if you want your tool to be one binary instead of a ball of loose dependencies, you want libponyc-standalone.

Pony Gets an Embedded Linker

As of ponylang/ponyc 0.61.1, the compiler carries its own linker. When you compile a Pony program on Linux, macOS, or Windows, ponyc no longer shells out to an external tool to produce your binary. It calls LLD directly, in-process, using the same LLVM infrastructure it already uses for code generation. Cross-compilation to Linux targets works the same way. The compiler is more self-contained than it’s ever been, and cross-compilation just got a lot simpler.