Skip to main content

Command Palette

Search for a command to run...

The State of GALA: March 2026

46 releases, 216 tests, 22x faster compilation — two months of building a language that transpiles to Go

Updated
6 min read
M

Senior Software Engineer at Snowflake. Expert in scalable architecture, cloud tech, and security. Passionate problem-solver and mentor.

What Is GALA?

GALA (Go Alternative Language) is a programming language that transpiles to Go. It takes Go's runtime performance, static typing, and deployment simplicity, and adds the features that Go developers reach for repeatedly but never get: sealed types with exhaustive pattern matching, immutability by default, monadic error handling, functional collections, and type inference that actually works across generic boundaries.

GALA is not a new runtime or a managed language. Every .gala file becomes a .go file. Your existing Go libraries, tools, and deployment pipelines work unchanged. The goal is simple: write safer, more expressive code that compiles to the same fast binaries you already rely on.

Two months ago, GALA shipped version 0.0.1 -- a transpiler that could handle basic structs, val/var declarations, and simple pattern matching. Today, version 0.25.2 delivers a language with a rich standard library, a zero-reflection JSON codec, async primitives, and a compilation pipeline that processes multi-file packages in under 3 seconds.

By the Numbers

Since the first release on January 23, 2026:

  • 46 releases shipped (roughly one every 1.5 days)
  • 216 verification examples in the test suite
  • 80+ bug fixes across type inference, code generation, and build tooling
  • 19 standard library modules (std, collections, concurrent, json, regex, io, go_interop)
  • 22x compilation speedup for multi-file packages (44.7s down to 2.7s)

This pace was only possible because GALA's transpilation architecture allows rapid iteration: change the transformer, run the examples, see real Go output. No bootstrapping a VM, no managing a garbage collector.

Highlight Reel

Sealed Types and Exhaustive Pattern Matching

Sealed types are GALA's answer to Go's lack of sum types. They define algebraic data types concisely, with the transpiler generating all the boilerplate -- parent structs, companion objects, Apply/Unapply methods, and discriminator checks.

sealed type Shape {
    case Circle(Radius float64)
    case Rectangle(Width float64, Height float64)
    case Point()
}

val area = shape match {
    case Circle(r)      => 3.14159 * r * r
    case Rectangle(w, h) => w * h
    case Point()         => 0.0
    // No default needed -- compiler verifies exhaustiveness
}

The standard library's Option[T], Either[A, B], and Try[T] are all sealed types. They use the same resolution mechanisms as user-defined types -- no special-casing in the transpiler.

Zero-Reflection JSON Codec

GALA's JSON codec is built on StructMeta[T], a compiler intrinsic that provides type-safe struct introspection without any reflection at runtime. The codec uses a builder pattern with naming strategies:

import . "martianoff/gala/json"

struct Person(FirstName string, LastName string, Age int)

val codec = Codec[Person](SnakeCase())
    .Omit("Password")
    .Rename("Email", "email_address")

val jsonStr = codec.Encode(person).Get()
// => {"first_name":"Alice","last_name":"Smith","age":30}

// Pattern matching on JSON strings
val result = jsonStr match {
    case codec(p) => s"Found: ${p.FirstName}, age ${p.Age}"
    case _ => "invalid JSON"
}

No struct tags. No encoding/json at runtime. The transpiler generates specialized, typed serialization code.

Functional Collections

GALA ships immutable Array, List, HashMap, TreeMap, HashSet, and TreeSet with full functional APIs:

import . "martianoff/gala/collection_immutable"

val nums = ArrayOf(1, 2, 3, 4, 5)
val doubled = nums.Map((x) => x * 2)
val sum = nums.FoldLeft(0, (acc, x) => acc + x)
val evens = nums.Filter((x) => x % 2 == 0)

// Collect: filter + transform in one pass
val evenDoubled = nums.Collect({ case n if n % 2 == 0 => n * 2 })

Sequence pattern matching works on any collection implementing the Seq interface:

val result = list match {
    case List(head, tail...) => s"First: $head, rest: ${tail.Size()}"
    case _ => "empty"
}

Monadic Error Handling: Try, Either, Future

Try[T] catches panics and wraps them as Failure, enabling railway-oriented programming without if err != nil chains:

val result = Try(() => riskyOperation())
    .Map((v) => v * 2)
    .Recover((e) => 0)

val msg = result match {
    case Success(v) => s"Got: $v"
    case Failure(e) => s"Error: ${e.Error()}"
}

Future[T] provides async computation with familiar monadic operations:

import . "martianoff/gala/concurrent"

val async = FutureApply[int](() => expensiveComputation())
val doubled = async.Map((v) => v * 2)
val value = doubled.Await().GetOrElse(0)

Default Parameters and Named Arguments

Functions support default values and named arguments -- the compiler reorders and injects them at the call site:

func connect(host string, port int = 8080, tls bool = true) Connection {
    // ...
}

connect("localhost")                // port=8080, tls=true
connect("localhost", tls = false)   // port=8080, tls=false

Named arguments also work with struct construction and Copy() method overrides.

String Interpolation

Two forms: s"..." for standard interpolation and f"..." for explicit format control:

val name = "world"
val pi = 3.14159
Println(s"Hello $name")        // Hello world
Println(f"$pi%.2f")            // 3.14

Auto-detected format verbs: %s for strings, %d for ints, %g for floats, %t for bools. No import needed for Println or Print.

22x Faster Compilation

Version 0.24.0 introduced batch transpilation, bringing multi-file package compilation from 44.7 seconds down to 2.7 seconds. The key insight: each file in a package was re-analyzing the entire dependency graph from scratch. Sharing analysis state across files in the same package eliminated the redundancy. See the companion blog post for the full story.

Retry Combinator

Version 0.25.0 added a retry combinator with pluggable backoff strategies:

import . "martianoff/gala/concurrent"

val result = Retry(
    maxRetries = 3,
    backoff = ExponentialBackoff(100),
    fn = () => fetchFromAPI(),
)

Three strategies ship out of the box: ConstantBackoff, ExponentialBackoff, and NoBackoff.

The Standard Library Today

PackagePurpose
stdOption, Either, Try, Tuple, StructMeta, Immutable
collection_immutableArray, List, HashMap, TreeMap, HashSet, TreeSet
concurrentFuture, Promise, ExecutionContext, Retry
jsonZero-reflection codec with builder pattern
regexPattern matching extractors for regular expressions
ioLazy IO effect type with composition
go_interopSliceOf, MapOf, nil-safe helpers for Go interop

Every standard library module follows the same rules as user code. There are no special cases in the transpiler for std types -- if you can build Option[T], you can build your own monads the same way.

Showcase Projects

Several non-trivial projects have been built with GALA during development:

  • GALA Playground (https://gala-playground.fly.dev) -- a web-based editor with live transpilation, deployed on Fly.io
  • gala-server -- a 7-file HTTP server package that served as the real-world benchmark for compilation performance
  • State Machine -- demonstrating sealed types as state representations with exhaustive transition matching
  • Log Analyzer -- a functional pipeline using Try, regex pattern matching, and collection operations

What's Next

GALA is still young. The transpiler handles a broad set of Go interop scenarios, but there are rough edges -- particularly around complex generic type inference across package boundaries. The near-term focus is:

  1. Stability -- expanding the type inference regression suite beyond its current 14 cases
  2. Cross-package generics -- improving type resolution for external GALA modules
  3. IDE support -- GoLand plugin for GALA syntax highlighting and navigation
  4. Package registry -- making it easy to publish and consume GALA libraries

If you write Go and have wished for pattern matching, immutability, or proper sum types, give GALA a try. The playground is at https://gala-playground.fly.dev, and the full language specification is in the repository.

The transpiler is honest about what it is: a source-to-source compiler that generates readable Go. When something goes wrong, you can always read the output. That transparency is a feature, not a limitation.

GALA From the Ground Up

Part 6 of 9

A ten-part technical blog series exploring GALA — a modern programming language that brings sealed types, pattern matching, monadic error handling, and immutable-by-default semantics to the Go ecosystem. Each post takes a single concept, shows the problem it solves with real code, compares it to idiomatic Go, and is honest about trade-offs. Written for Go developers who want more expressiveness and functional programmers who want Go's runtime.

Up next

samber/lo Has 21K Stars. Here's What It Would Look Like as a Language Feature.

samber/lo has 21,000 stars. samber/mo has 3,300. Together, they represent one of the loudest feature requests the Go community has ever filed -- not through proposals or GitHub issues, but through ado