GALA transpiles to Go. Every Go package, type, and function is available in GALA code with zero friction. Your existing Go modules, third-party libraries, and tooling all work out of the box.
Standard Go imports work directly in GALA:
import "strings"
import "fmt"
import "net/http"
import "encoding/json"
Grouped imports are supported:
import (
"strings"
"net/http"
"os"
)
Aliased and dot imports work too:
import mystrings "strings"
import . "martianoff/gala/std"
Call any Go function with GALA’s syntax:
import "strings"
val upper = strings.ToUpper("hello") // "HELLO"
val parts = strings.Split("a,b,c", ",") // []string{"a","b","c"}
val contains = strings.Contains("hello", "ell") // true
Go functions that return (T, error) work naturally:
import "os"
val file, err = os.Open("data.txt")
if err != nil {
Println(s"Error: ${err.Error()}")
}
Or wrap them in Try for monadic error handling:
import "os"
import . "martianoff/gala/std"
val result = Try(() => os.Getwd())
val dir = result.GetOrElse("/tmp")
Define and use Go struct types with GALA syntax:
import "net/http"
// Go struct types work in GALA
var client = &http.Client{}
GALA structs are Go structs under the hood, so they interoperate seamlessly:
type Config struct {
var Host string
var Port int
}
// Pass to any Go function expecting this struct
val jsonBytes, _ = json.Marshal(Config{Host: "localhost", Port: 8080})
GALA supports Go-style type conversions:
// Numeric conversions
val n = int64(42)
val f = float64(10)
val i = int(3.14) // truncates to 3
// Rune/string conversions
val r = rune(65) // int to rune: 'A'
val s = string(r) // rune to string: "A"
For byte and rune slice conversions, use the go_interop helpers:
import . "martianoff/gala/go_interop"
val bytes = ToBytes("hello") // string to []byte
val str = ToString(bytes) // []byte to string
val runes = ToRunes("hello") // string to []rune
[]T InteropGALA collections (Array, List) are preferred for general programming. When you need Go’s native []T — for passing data to Go libraries or variadic arguments — use the go_interop package:
import . "martianoff/gala/go_interop"
val goSlice = SliceOf(1, 2, 3, 4, 5) // Go []int
val empty = SliceEmpty[int]() // Go []int{}
val withCap = SliceWithCapacity[int](10) // []int with capacity 10
Convert between GALA collections and Go slices:
import . "martianoff/gala/collection_immutable"
import . "martianoff/gala/go_interop"
// GALA Array → Go slice
val arr = ArrayOf(1, 2, 3)
val goSlice = arr.ToGoSlice()
// Go slice → GALA Array
val backToArray = ArrayFromSlice(goSlice)
| Use Case | Recommendation |
|---|---|
| General programming | Array or List from collection_immutable |
| Need Map/Filter/FoldLeft | Array or List (full functional API) |
| Passing data to Go libraries | SliceOf from go_interop, or .ToGoSlice() |
| Variadic function arguments | Go slices with SliceOf |
| Function | Description |
|---|---|
SliceOf(elements...) |
Create Go slice from values |
SliceEmpty[T]() |
Create empty Go slice |
SliceWithCapacity[T](cap) |
Empty slice with capacity |
SliceCopy(slice) |
Copy a slice |
SliceAppendAll(dst, src) |
Append all elements |
SlicePrepend(s, value) |
Insert at front |
SliceTake(s, n) |
Take first n elements |
SliceDrop(s, n) |
Drop first n elements |
map[K]V InteropGALA’s HashMap is preferred for most use cases. When you need Go-native map[K]V for interoperability:
import . "martianoff/gala/std"
// Create and populate
var goMap = MapEmpty[string, int]()
goMap = MapPut(goMap, "key", 42)
// Query
val value, ok = MapGet(goMap, "key")
val exists = MapContains(goMap, "key")
// Iterate
MapForEach(goMap, (k string, v int) => {
Println(s"$k: $v")
})
Convert between HashMap and Go map:
import "martianoff/gala/collection_immutable"
val hashMap = collection_immutable.HashMapFromGoMap(goMap)
val backToGoMap = hashMap.ToGoMap()
| Function | Description |
|---|---|
MapEmpty[K, V]() |
Create empty map |
MapPut(m, k, v) |
Add/update entry, returns map |
MapGet(m, k) |
Get value and existence flag |
MapContains(m, k) |
Check if key exists |
MapDelete(m, k) |
Remove key, returns map |
MapLen(m) |
Number of entries |
MapForEach(m, f) |
Iterate all entries |
Go’s built-in functions are available directly:
val length = len("hello") // 5
val sliceCap = cap(mySlice) // slice capacity
val ch = make(chan int, 10) // buffered channel
// Println and Print are available without importing fmt
Println("hello world")
Print("no newline")