The sum types, exhaustive pattern matching, and Option types Go still doesn't have — as a language, not a library. Option/Either/Try monads, zero-reflection JSON, first-class interop with every Go module, native binaries.
sealed type Shape {
case Circle(Radius float64)
case Rectangle(Width float64, Height float64)
}
func area(s Shape) string = s match {
case Circle(r) => f"circle: ${3.14159 * r * r}%.2f"
case Rectangle(w, h) => f"rect: ${w * h}%.2f"
}
GALA — Go Alternative LAnguage — is a statically typed, functional-first language that transpiles to Go.
The 2024 Go Developer Survey found that sum types are the #1 most-requested missing feature in Go. As of Go 1.25 they still don’t exist. GALA delivers them — and organizes everything else around three promises.
Sum types with exhaustive pattern matching (an incomplete match is a build error, not a production panic), no nil (Option/Either/Try instead), immutable by default (val, immutable structs, read-only ConstPtr), always-concrete types — never a silent any — and zero-reflection typed JSON. The transpiler enforces match exhaustiveness and immutability at compile time.
sealed type Payment {
case Card(Last4 string)
case Cash()
}
func describe(p Payment) string = p match {
case Card(n) => s"card ****$n"
case Cash() => "cash"
} // omit a case and it won't compile
bind/also do-notation for composing monads, string interpolation (s"…" / f"…"), named arguments and default parameters, type inference everywhere, expression functions, and Map/Filter/FoldLeft/Collect collections. These are language features with clean syntax — not patterns bolted onto Go like samber/lo or IBM/fp-go.
func checkout(id int) Try[Receipt] {
bind order = fetchOrder(id) // unwraps Try, or short-circuits
bind payment = charge(order)
Success(Receipt(order.Id, payment))
}
Full third-party Go interop with return types inferred directly from the Go SDK — no declaration files to write or generate. Wrap a Go (T, error) call in Try and it becomes a Try[T], the generated Go is clean and readable, and it builds to a single native binary inside your existing Go project. No runtime overhead beyond hand-written Go.
import "strconv"
// a Go (int, error) call, wrapped into Try[int]
val port = Try(strconv.Atoi("8080")).GetOrElse(80)
Pattern matching is one of the most visible differences between GALA and Go. Idiomatic Go handles a closed set with a type switch, but it destructures nothing for you and never checks that every case is covered. GALA destructures values directly and enforces exhaustiveness at compile time.
GALA
val msg = shape match {
case Circle(r) => f"r=$r%.1f"
case Rectangle(w, h) => f"$w%.0fx$h%.0f"
case Point() => "point"
}
Go
var msg string
switch s := shape.(type) {
case Circle:
msg = fmt.Sprintf("r=%.1f",
s.Radius)
case Rectangle:
msg = fmt.Sprintf("%.0fx%.0f",
s.Width, s.Height)
case Point:
msg = "point"
}
GALA’s version is shorter, handles destructuring automatically, and produces a compile-time error if you forget a case. See the full GALA vs Go comparison for more examples including Option handling, immutable structs, and error handling.
Define closed type hierarchies. The compiler rejects incomplete matches — no forgotten cases at runtime.
sealed type Shape {
case Circle(Radius float64)
case Rectangle(Width float64, Height float64)
}
Exhaustive pattern matching with destructuring, guards, and expression results — far beyond Go's switch.
val msg = shape match {
case Circle(r) => f"r=$r%.1f"
case Rectangle(w, h) => f"${w * h}%.2f"
}
val bindings are immutable. Struct fields are immutable. Auto-generated Copy() for safe updates.
struct Config(Host string, Port int)
val updated = config.Copy(Port = 8080)
Option[T], Either[A,B], and Try[T] replace nil checks and if err != nil with composable pipelines.
val result = divide(10, 2)
.Map((x) => x * 2)
.FlatMap((x) => divide(x, 3))
.Recover((e) => 0)
bind / also)Do-notation for any monad. bind flattens FlatMap chains; also marks independent steps that accumulate errors (Validated) or run concurrently (Future).
func processOrder(id int) Try[Receipt] {
bind o = fetchOrder(id)
bind valid = validateOrder(o)
bind payment = chargePayment(valid)
Success(Receipt(o.Id, payment))
}
Immutable List, Array, HashMap, HashSet, TreeSet, TreeMap with Map, Filter, FoldLeft, Collect, and more.
val nums = ArrayOf(1, 2, 3, 4, 5)
val evens = nums.Filter((x) => x % 2 == 0)
val sum = nums.FoldLeft(0, (acc, x) => acc + x)
No more functional options pattern or config structs. Default parameter values and named arguments work directly in function signatures.
func connect(host string,
port int = 8080, tls bool = true,
) Connection
connect("localhost", tls = false)
Compile-time StructMeta[T] generates typed serialization with no reflection, no struct tags. Builder pattern for Rename, Omit, and naming strategies.
val codec = Codec[Person](SnakeCase())
val jsonStr = codec.Encode(person).Get()
val decoded = codec.Decode(jsonStr)
Compile-safe regex with extractors that destructure capture groups directly in match expressions. No manual group indexing.
val date = regex.MustCompile(
"(\\d{4})-(\\d{2})-(\\d{2})")
input match {
case date(Array(y, m, d)) =>
s"$y/$m/$d"
}
Use any Go library. Go imports, Go types, and Go functions work directly in GALA code. One ecosystem, zero friction.
import "strings"
val name = user.Name
.Map((n) => strings.ToUpper(n))
.GetOrElse("ANONYMOUS")
GoLand/IntelliJ plugin with syntax highlighting, type-aware dot completion, inlay type hints, and structure view. LSP server provides diagnostics, hover, go-to-definition, and more.
Download a pre-built binary from Releases for Linux, macOS, or Windows. Or build from source:
git clone https://github.com/martianoff/gala.git && cd gala
bazel build //cmd/gala:gala
Create main.gala:
package main
struct Person(Name string, Age int)
func greet(p Person) string = p match {
case Person(name, age) if age < 18 => s"Hey, $name!"
case _ => s"Hello, ${p.Name}"
}
func main() {
Println(greet(Person("Alice", 25)))
}
gala mod init example.com/hello
gala run main.gala
Or with Bazel for larger projects:
bazel run //myapp:myapp
See the full Getting Started guide for project setup, Bazel integration, and dependency management.
GALA ships with a standard library of type-safe data structures and monads, all built on sealed types and functional programming patterns.
| Type | Description | Documentation |
|---|---|---|
Option[T] |
Optional values — Some(value) / None() |
Monadic types |
Either[A, B] |
Disjoint union — Left(a) / Right(b) |
Monadic types |
Try[T] |
Failable computation — Success(value) / Failure(err) |
Monadic types |
Future[T] |
Async computation with Map, FlatMap, Zip, Await |
Concurrency |
Tuple[A, B] |
Pairs and triples with (a, b) syntax |
Language spec |
ConstPtr[T] |
Read-only pointer with compile-time enforcement | Immutability |
Codec[T] |
Zero-reflection JSON codec — Encode, Decode, Rename, Omit, pattern matching |
JSON codec |
Regex |
Regular expressions with Unapply for pattern matching |
Regex |
IO[T] |
Lazy composable effects — Of, Suspend, Map, FlatMap |
IO effect |
| Type | Kind | Key Operations | Best for |
|---|---|---|---|
List[T] |
Immutable | O(1) prepend, O(n) index | Recursive processing |
Array[T] |
Immutable | O(1) random access | General-purpose sequences |
HashMap[K,V] |
Immutable | O(1) lookup | Key-value storage |
HashSet[T] |
Immutable | O(1) membership | Unique element collections |
TreeSet[T] |
Immutable | O(log n) sorted ops | Ordered unique elements |
TreeMap[K,V] |
Immutable | O(log n) sorted ops | Sorted key-value storage |
All collections support Map, Filter, FoldLeft, ForEach, Exists, Find, Collect, MkString, Sorted, and more. Mutable variants are available in collection_mutable for performance-sensitive code. See the collections documentation for details.
| Document | Description |
|---|---|
| Language Specification | Complete reference for GALA syntax and semantics |
| Getting Started | Installation, project setup, and first program |
| GALA vs Go | Side-by-side comparison with idiomatic Go |
| Sealed Types | Algebraic data types and closed hierarchies |
| Pattern Matching | Exhaustive matching, destructuring, and guards |
| Immutability | val, immutable structs, Copy(), and ConstPtr[T] |
| Error Handling | Option[T], Either[A,B], Try[T] monads |
| Collections | Immutable and mutable functional collections |
| Concurrency | Future[T], Promise[T], and ExecutionContext |
| JSON Codec | Zero-reflection JSON serialization with Codec[T] |
| Regex | Pattern matching with regex extractors |
| IO Effect | Lazy, composable side effects |
| Go Interop | Using Go libraries and types from GALA |
| Playground | Try GALA in your browser — no install needed |
| Project | Description |
|---|---|
| GALA Playground | Web-based playground — try it live |
| State Machine Example | State machines with sealed types and pattern matching |
| Log Analyzer | Structured log parsing with Go stdlib interop and functional pipelines |
| GALA Server | Immutable HTTP server library with builder-pattern configuration |
| GALA TUI | Elm-architecture TUI framework — immutable widgets, differential renderer, async runtime |
| GALA Team | Multi-agent Claude CLI orchestrator — Team Lead delegates to Engineers and QAs, reviews work, hands you a PR |