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.
That extends to Go’s worst production bug class: data races are a compile error. A value crossing a goroutine boundary must be deeply immutable, and the transpiler proves it before the program runs — no sampling, no -race build, no interleaving you happened not to hit. Because GALA is immutable by default the check is silent in the common case; it fires only on genuinely mutable state (GALA-E0037).
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"
}
Only deeply-immutable values may cross a goroutine boundary. A Future body that captures mutable state is a build error (GALA-E0037), not a race you find in production.
var counter = 0
Future(() => counter + 1)
// GALA-E0037: captures
// reassignable var "counter"
Future[T] composes with Map/FlatMap/Zip, and bounds itself: Cancel(), WithTimeout, and Race short-circuit pending stages instead of leaking them.
val bounded = slow
.WithTimeout(Milliseconds(500))
.Recover((e) => 0)
Rust/Elm-style framed diagnostics with a caret and a fix. Panics report foo.gala:12, not generated Go. Self-tail-recursive functions become constant-stack loops.
error[GALA-E0035]: bare Go builtin
"len(...)" is not part of GALA's surface
--> bare_len.gala:5:13
|
5 | val n = len(s)
| ^^^ use `.Size()`
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)
Compile-time StructMeta[T] generates typed serialization with no reflection, no struct tags — for JSON and YAML alike. 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"
case _ => "not a date"
}
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. The LSP server adds diagnostics, hover, and go-to-definition — including into Go stdlib and third-party Go module sources.
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, Cancel, WithTimeout |
Concurrency |
Sendable[F] |
Transparent concurrency-boundary marker — compile-time capture safety | Concurrency safety |
Validated[E, A] |
Accumulating validation — Valid / Invalid, Zip2…Zip10 |
Monadic binding |
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 Reference | Complete reference for GALA syntax and semantics |
| All Documentation | Documentation hub — every guide and standard-library page |
| 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], ExecutionContext, cancellation, timeouts, Race |
| Concurrency Safety | Compile-time data-race safety — Shareable, Sendable, GALA-E0037 |
| Compiler DX | Framed diagnostics, GALA-source stack traces, guaranteed TCO, use |
| Subprocess | Spawn and drive child processes, with Future-returning async methods |
| JSON Codec | Zero-reflection JSON serialization with Codec[T] |
| YAML Codec | Zero-reflection YAML serialization with the same builder API |
| 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 |