Coming from Go
Every section below is a Go pattern with a Lisette equivalent.
Bindings
Section titled “Bindings”count := 5total := 0total += countbindings.go
let count = 5let mut total = 0total += countbindings.lis
See Bindings
Functions
Section titled “Functions”func add(a int, b int) int { return a + b}add.go
fn add(a: int, b: int) -> int { a + b}add.lis
See Functions
Lambdas
Section titled “Lambdas”sort.Slice(scores, func(i, j int) bool { return scores[i] < scores[j]})sort.go
sort.Slice(scores, |i, j| scores[i] < scores[j])sort.lis
See Lambdas
Pipeline
Section titled “Pipeline”trimmed := strings.TrimSpace(" Hello World ")lowered := strings.ToLower(trimmed)result := strings.ReplaceAll(lowered, " ", "-")slug.go
let result = " Hello World " |> strings.TrimSpace |> strings.ToLower |> strings.ReplaceAll(" ", "-")slug.lis
See Operators
for i := 0; i < 10; i++ { fmt.Println(i)}
for _, line := range lines { fmt.Println(line)}
for { if queue.IsEmpty() { break }}loops.go
for i in 0..10 { fmt.Println(i)}
for line in lines { fmt.Println(line)}
loop { if queue.is_empty() { break }}loops.lis
See Control flow
Structs
Section titled “Structs”type User struct { Name string email string}
u := User{Name: "Alice", email: "a@b.com"}user.go
struct User { pub name: string, email: string,}
let u = User { name: "Alice", email: "a@b.com" }user.lis
See Structs
Pointers
Section titled “Pointers”func rename(u *User, name string) { u.Name = name}
user := User{Name: "Alice", email: "a@b.com"}rename(&user, "Bob")pointer.go
fn rename(u: mut Ref<User>, name: string) { u.name = name}
let mut user = User { name: "Alice", email: "a@b.com" }rename(&user, "Bob")pointer.lis
See References
type Severity int
const ( Low Severity = iota High Critical)severity.go
enum Severity { Low, High, Critical }severity.lis
A match on an enum must cover every variant.
switch s {case Low, High: fmt.Println("ignore")case Critical: fmt.Println("alert")}severity.go
match s { Low | High => fmt.Println("ignore"), Critical => fmt.Println("alert"),}severity.lis
See Enums and Pattern matching
Collections
Section titled “Collections”nums := []int{1, 2, 3}nums = append(nums, 4)
buf := make([]byte, 1024)
ages := make(map[string]int)ages["Alice"] = 20age, ok := ages["Bob"]collections.go
let nums = [1, 2, 3]let nums = nums.append(4)
let buf = Slice.make<byte>(1024)
let mut ages = Map.new<string, int>()ages["Alice"] = 20let age = ages.get("Bob")Option<int>collections.lis
Methods
Section titled “Methods”func (r Rectangle) Area() float64 { return r.Width * r.Height}
func (r *Rectangle) Scale(factor float64) { r.Width *= factor r.Height *= factor}rectangle.go
impl Rectangle { fn area(self) -> float64 { self.width * self.height }
fn scale(self: mut Ref<Rectangle>, factor: float64) { self.width *= factor self.height *= factor }}rectangle.lis
See Methods
Interfaces
Section titled “Interfaces”type Reader interface { Read(p []byte) (n int, err error)}reader.go
interface Reader { fn Read(p: mut Slice<byte>) -> Partial<int, error>}reader.lis
See Interfaces
Error handling
Section titled “Error handling”bytes, err := os.ReadFile(path)if err != nil { return Config{}, err}return parseConfig(bytes)handle.go
let bytes = os.ReadFile(path)?parse_config(bytes)handle.lis
The ? operator unwraps Ok or returns early with Err. Functions returning (T, error) in Go become Result<T, error> in Lisette.
See Failures
Absence handling
Section titled “Absence handling”var user *Userpointer can be nilif user != nil { fmt.Println(user.Name)}lookup.go
let user = get_user(id)Option<Ref<User>>if let Some(u) = user { fmt.Println(u.name)}lookup.lis
Ref<T> is guaranteed non-nil. Nilable pointers become Option<Ref<T>>.
Concurrency
Section titled “Concurrency”ch := make(chan int)go func() { ch <- 42}()v := <-chworker.go
let ch = Channel.new<int>()task ch.send(42)let v = ch.receive()Option<int>worker.lis
See Concurrency