Gala
GALA (Go Alternative LAnguage) -- a modern functional programming language that transpiles to Go. Sealed types, pattern matching, immutability by default, monads (Option, Either, Try, Future), and full Go interop. Built with Go, ANTLR4, Bazel and Claude.
Install / Use
/learn @martianoff/GalaREADME
GALA
<img alt="GALA Logo" height="384" src="gala_escape.png" width="700"/>GALA (Go Alternative LAnguage) is a modern programming language that transpiles to Go. It brings sealed types, pattern matching, immutability by default, and functional collections to the Go ecosystem -- without sacrificing Go's performance, tooling, or library compatibility.
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 area: ${3.14159 * r * r}%.2f"
case Rectangle(w, h) => f"rect area: ${w * h}%.2f"
}
What is GALA?
GALA gives you Scala-like expressiveness -- sealed types, exhaustive pattern matching, Option[T]/Either[A,B]/Try[T] monads, immutable collections -- in a concise, readable syntax that compiles to a single native binary. GALA is fully Go-compatible: every Go library works out of the box.
Key Features
Sealed types and exhaustive pattern matching -- Define closed type hierarchies. The compiler rejects incomplete matches.
sealed type Result[T any] {
case Ok(Value T)
case Err(Message string)
}
val msg = result match {
case Ok(v) => s"got $v"
case Err(msg) => s"error: $msg"
}
Immutability by default -- val and := are immutable. Structs auto-generate Copy() and Equal().
struct Config(Host string, Port int)
val updated = config.Copy(Port = 8080)
Expression functions -- Single-expression functions skip braces and return.
func square(x int) int = x * x
func max(a int, b int) int = if (a > b) a else b
Default parameters and named arguments -- Skip boilerplate. Defaults are evaluated at each call site; named arguments can appear in any order.
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
connect(host = "db", port = 5432) // tls=true
Lambda type inference -- Parameter types and method type parameters are inferred from context.
val list = ListOf(1, 2, 3)
val doubled = list.Map((x) => x * 2)
val sum = list.FoldLeft(0, (acc, x) => acc + x)
Monads -- Option[T], Either[A,B], Try[T], Future[T] with Map, FlatMap, Recover, and pattern matching.
val name = user.Name
.Map((n) => strings.ToUpper(n))
.GetOrElse("ANONYMOUS")
Functional collections -- 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 evenDoubled = nums.Collect({ case n if n % 2 == 0 => n * 2 })
Tuples with destructuring -- Up to Tuple5, with pattern matching and concise syntax.
val pair = (1, "hello")
val (x, y) = pair
Read-only pointers -- ConstPtr[T] prevents accidental mutation through pointers.
val data = 42
val ptr = &data // ConstPtr[int], not *int
val value = *ptr // OK: read
// *ptr = 100 // compile error: cannot write through ConstPtr
String interpolation -- s"..." with auto-inferred format verbs and f"..." with explicit format specs. No imports needed.
val name = "Alice"
val age = 30
Println(s"$name is $age years old") // Alice is 30 years old
Println(f"Pi = ${3.14159}%.2f") // Pi = 3.14
Println(s"${nums.MkString(", ")}") // 1, 2, 3
Zero-reflection JSON codec -- Codec[T] uses the compiler-generated StructMeta[T] intrinsic for fully typed serialization with no reflection, no struct tags, and pattern matching support.
struct Person(FirstName string, LastName string, Age int)
val codec = Codec[Person](SnakeCase())
val jsonStr = codec.Encode(Person("Alice", "Smith", 30)).Get()
// {"first_name":"Alice","last_name":"Smith","age":30}
val decoded = codec.Decode(jsonStr) // Try[Person]
val name = jsonStr match {
case codec(p) => p.FirstName // pattern matching!
case _ => "unknown"
}
Regex with pattern matching -- Compile-safe regex with extractors that destructure capture groups directly in match.
val dateRegex = regex.MustCompile("(\\d{4})-(\\d{2})-(\\d{2})")
"2024-01-15" match {
case dateRegex(Array(year, month, day)) => s"$year/$month/$day"
case _ => "not a date"
}
Full Go interop -- Use any Go library. Go function return types are automatically inferred from the Go SDK, and multi-return (T, error) patterns are wrapped into Try[T].
Fast compilation -- Analysis caching and batch transpilation make multi-file packages compile up to 16x faster. Profile bottlenecks with GALA_PROFILE=1.
Quick Start
1. Install
Download a pre-built binary from Releases, or build from source:
git clone https://github.com/martianoff/gala.git && cd gala
bazel build //cmd/gala:gala
2. Write
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 Person(name, _) => s"Hello, $name"
}
func main() {
Println(greet(Person("Alice", 25)))
}
3. Run
gala run main.gala # Transpile + compile + run
gala build # Build project to binary
gala test # Run tests
gala run examples/hello/main.gala # Run subdirectory executable
# Or with Bazel (recommended for larger projects)
bazel build //... && bazel test //...
GALA vs Go
Pattern Matching vs Switch
<table> <tr><th>GALA</th><th>Go</th></tr> <tr> <td>val msg = shape match {
case Circle(r) => f"r=$r%.1f"
case Rectangle(w,h) => f"$w%.0fx$h%.0f"
case Point() => "point"
}
</td>
<td>
var msg string
switch shape._variant {
case Shape_Circle:
msg = fmt.Sprintf("r=%.1f", shape.Radius.Get())
case Shape_Rectangle:
msg = fmt.Sprintf("%fx%f", shape.Width.Get(), shape.Height.Get())
case Shape_Point:
msg = "point"
}
</td>
</tr>
</table>
Option Handling vs nil Checks
<table> <tr><th>GALA</th><th>Go</th></tr> <tr> <td>val name = user.Name
.Map((n) => strings.ToUpper(n))
.GetOrElse("ANONYMOUS")
</td>
<td>
name := "ANONYMOUS"
if user.Name != nil {
name = strings.ToUpper(*user.Name)
}
</td>
</tr>
</table>
Immutable Structs vs Manual Copying
<table> <tr><th>GALA</th><th>Go</th></tr> <tr> <td>struct Config(Host string, Port int)
val updated = config.Copy(Port = 8080)
</td>
<td>
type Config struct {
Host string
Port int
}
updated := Config{Host: config.Host, Port: 8080}
</td>
</tr>
</table>
Default Parameters vs Option Structs
<table> <tr><th>GALA</th><th>Go</th></tr> <tr> <td>func connect(
host string,
port int = 8080,
tls bool = true,
) Connection
connect("localhost", tls = false)
</td>
<td>
type ConnectOptions struct {
Host string
Port int
TLS *bool
}
func Connect(opts ConnectOptions) Connection {
if opts.Port == 0 { opts.Port = 8080 }
if opts.TLS == nil {
t := true; opts.TLS = &t
}
// ...
}
Connect(ConnectOptions{Host: "localhost", TLS: ptrBool(false)})
</td>
</tr>
</table>
Error Handling: Try vs if-err
<table> <tr><th>GALA</th><th>Go</th></tr> <tr> <td>val result = divide(10, 2)
.Map((x) => x * 2)
.FlatMap((x) => divide(x, 3))
.Recover((e) => 0)
</td>
<td>
result, err := divide(10, 2)
if err != nil {
result = 0
} else {
result = result * 2
result, err = divide(result, 3)
if err != nil {
result = 0
}
}
</td>
</tr>
</table>
Standard Library
Types
| Type | Description |
|------|-------------|
| Option[T] | Optional values -- Some(value) / None() |
| Either[A, B] | Disjoint union -- Left(a) / Right(b) |
| Try[T] | Failable computation -- Success(value) / Failure(err) |
| Future[T] | Async computation with Map, FlatMap, Zip, Await |
| Tuple[A, B] | Pairs and triples with (a, b) syntax |
| ConstPtr[T] | Read-only pointer with auto-deref field access |
| IO[T] | Lazy, composable effect type -- Suspend, Map, FlatMap, Recover |
JSON, Regex, IO
| Type | Description |
|------|-------------|
| Codec[T] | Zero-reflection JSON codec with Encode, Decode, Rename, Omit, pattern matching |
| Regex | Compiled regex with Matches, FindFirst, FindAll, ReplaceAll, pattern matching |
| IO[T] | Lazy effect -- separates description from execution, re-runs on every .Run() |
Collections
| Type | Kind | Key Operations | Best for |
|------|------|----------------|----------|
| List[T] | Immutable | O(1) prepend, O(n) index | Recursive processing, prepend-heavy workloads |
| Array[T] | Immutabl
Related Skills
xurl
348.5kA CLI tool for making authenticated requests to the X (Twitter) API. Use this skill when you need to post tweets, reply, quote, search, read posts, manage followers, send DMs, upload media, or interact with any X API v2 endpoint.
clearshot
Structured screenshot analysis for UI implementation and critique. Analyzes every UI screenshot with a 5×5 spatial grid, full element inventory, and design system extraction — facts and taste together, every time. Escalates to full implementation blueprint when building. Trigger on any digital interface image file (png, jpg, gif, webp — websites, apps, dashboards, mockups, wireframes) or commands like 'analyse this screenshot,' 'rebuild this,' 'match this design,' 'clone this.' Skip for non-UI images (photos, memes, charts) unless the user explicitly wants to build a UI from them. Does NOT trigger on HTML source code, CSS, SVGs, or any code pasted as text.
openpencil
2.0kThe world's first open-source AI-native vector design tool and the first to feature concurrent Agent Teams. Design-as-Code. Turn prompts into UI directly on the live canvas. A modern alternative to Pencil.
ui_ux_excellence
UI/UX Design Excellence 🎨 Core UI/UX Design Role AI operates as Elite UI/UX Designer with these responsibilities: 1. Design System Authority - Enforce consistent, pixel-perfect implem
