GoloScript Structures Guide

This guide presents structures (structs) and augmentation in GoloScript.


Introduction

GoloScript offers a powerful mechanism for creating custom types: structures (structs) with augmentation.

β˜… Insight ─────────────────────────────────────
Struct Architecture: GoloScript structs are similar to Go structs or Java records - they define a fixed structure with typed fields at definition time, offering better performance and validation.

Augmentation: GoloScript’s augmentation system is similar to C#'s β€œextension methods” or Swift’s β€œprotocols” - it allows adding behaviors to existing types without modifying their original definition. It’s a composition pattern that avoids the problems of traditional inheritance.
─────────────────────────────────────────────────


Structs - Basics

Definition

struct Point = { x, y }
struct Person = { name, age }
struct Rectangle = { width, height }

Creation

let p1 = Point(10, 20)
let alice = Person("Alice", 30)
let rect = Rectangle(50, 30)

Field Access

println(p1: x())        # 10
println(p1: y())        # 20
println(alice: name())  # Alice
println(alice: age())   # 30

Field Modification

# Setters
p1: x(100)
p1: y(200)
println(p1)  # Point(x=100, y=200)

# Chained initialization
let rect = Rectangle(0, 0)
  : width(50)
  : height(30)

Built-in Struct Methods

All structs automatically inherit useful methods:

Copy Methods

Method Description Example
copy() Mutable copy let copy = person: copy()
frozenCopy() Immutable copy let frozen = person: frozenCopy()
isFrozen() Check if immutable person: isFrozen()
let alice = Person("Alice", 30)

# Mutable copy
let aliceCopy = alice: copy()
aliceCopy: age(31)
# alice remains unchanged

# Immutable copy (frozen)
let aliceFrozen = alice: frozenCopy()
println(aliceFrozen: isFrozen())  # true
# aliceFrozen: age(32)  # Error! Cannot modify

Comparison Methods

Method Description Returns
equals(other) Equality Boolean
hashCode() Hash code Integer
compareTo(other) Comparison Integer (-1, 0, 1)

Supported operators: <, >, <=, >=, ==

let p1 = Point(10, 20)
let p2 = Point(10, 20)
println(p1: equals(p2))  # true

let person1 = Person("Alice", 30)
let person2 = Person("Bob", 25)
println(person1 < person2)  # true (lexicographic order)

Introspection Methods

Method Description Returns
members() Field names Array of String
values() Field values Array
get(name) Value by name Object
set(name, val) Modify by name void
let alice = Person("Alice", 30)

# Introspection
println(alice: members())  # [name, age]
println(alice: values())   # [Alice, 30]
println(alice: get("age")) # 30
alice: set("age", 31)      # Modifies age

Simple Augmentation

Augmentation adds custom methods to structs.

Syntax

struct Person = { name, age }

augment Person {
  function greet = |this| {
    return "Hello, my name is " + this: name()
  }

  function isAdult = |this| {
    return this: age() >= 18
  }

  function birthday = |this| {
    this: age(this: age() + 1)
  }
}

Usage

let alice = Person("Alice", 30)
println(alice: greet())     # Hello, my name is Alice
println(alice: isAdult())   # true
alice: birthday()           # Increments age

Key Points


Named Augmentations

Named augmentations are reusable across multiple structs.

Definition

# Define reusable augmentation
augmentation Runnable = {
  function run = |this| {
    println(this: name() + " is running!")
  }

  function walk = |this| {
    println(this: name() + " is walking.")
  }
}

augmentation Ageable = {
  function birthday = |this| {
    this: age(this: age() + 1)
  }

  function isYoung = |this| {
    return this: age() < 3
  }
}

# Define specific augmentations
augmentation Woofable = {
  function woof = |this| {
    println(this: name() + " says: Woof!")
  }
}

augmentation Meowable = {
  function meow = |this| {
    println(this: name() + " says: Meow!")
  }
}

Application

struct Dog = { name, age, breed }
struct Cat = { name, age, color }

# Apply multiple augmentations
augment Dog with Runnable, Ageable, Woofable
augment Cat with Runnable, Ageable, Meowable

Usage

let rex = Dog("Rex", 5, "German Shepherd")
let whiskers = Cat("Whiskers", 2, "orange")

# Shared methods (Runnable, Ageable)
rex: run()
whiskers: run()
rex: birthday()
whiskers: birthday()

# Specific methods
rex: woof()
whiskers: meow()

Advantages


Advanced Methods

Copy and Modification

let alice = Person("Alice", 30)

# Mutable copy
let aliceCopy = alice: copy()
aliceCopy: age(31)
# alice remains unchanged

# Chained copy with modifications
let bob = alice: copy(): name("Bob"): age(28)

Equality and Hash Codes

let person1 = Person("Bob", 28)
let person2 = Person("Bob", 28)
let person3 = Person("Alice", 30)

println(person1: equals(person2))  # true
println(person1: equals(person3))  # false

println(person1: hashCode())  # -4193699580566542946
println(person2: hashCode())  # -4193699580566542946
# Equal objects have the same hashCode

Comparisons

let p1 = Person("Alice", 30)
let p2 = Person("Bob", 28)
let p3 = Person("Alice", 25)

# Comparison operators
println(p1 < p2)   # true (Alice < Bob)
println(p1 > p2)   # false

# Same name, compare by age
println(p1 > p3)   # true (30 > 25)

# compareTo method
println(p1: compareTo(p2))  # -1
println(p2: compareTo(p1))  #  1
println(p1: compareTo(p1))  #  0

Dynamic Introspection

let person = Person("Eve", 25)

# Get field names and values
let fieldNames = person: members()   # [name, age]
let fieldValues = person: values()   # [Eve, 25]

# Access by field name
let name = person: get("name")       # Eve
let age = person: get("age")         # 25

# Modify by field name
person: set("age", 26)
person: set("name", "Eva")

Patterns and Best Practices

When to Use Structs

Use Case Recommended Choice Reason
Fixed structured data Struct Performance, validation
Shared behavior Named Augmentation Reusability
Business model Struct + Augmentation Clarity, maintainability
Types with methods Struct + Augmentation Structure/behavior separation

Builder Pattern with Chaining

struct Configuration = { host, port, timeout, debug }

let config = Configuration("", 0, 0, false)
  : host("localhost")
  : port(8080)
  : timeout(30)
  : debug(true)

Augmentation Composition

# Create reusable "traits"
augmentation Displayable = {
  function toString = |this| {
    return this: name()
  }
}

augmentation Comparable = {
  function isEqual = |this, other| {
    return this: name() == other: name()
  }
}

# Compose
augment Person with Displayable, Comparable

Methods with Chaining

struct Person = { name, age, city }

augment Person {
  function birthday = |this| {
    this: age(this: age() + 1)
    return this  # Enables chaining
  }

  function relocate = |this, newCity| {
    this: city(newCity)
    return this
  }
}

# Chained usage
let person = Person("Alice", 30, "Paris")
person: birthday(): birthday(): relocate("Lyon")

Collections of Structs

let people = [
  Person("Alice", 30),
  Person("Bob", 25),
  Person("Charlie", 35)
]

# Iteration
foreach person in people {
  println(person: name(), "is", person: age(), "years old")
}

# Filtering with augmented methods
augment Person {
  function isAdult = |this| {
    return this: age() >= 18
  }
}

foreach person in people {
  if person: isAdult() {
    println(person: name(), "is an adult")
  }
}

Β© 2026 GoloScript Project | Built with Gu10berg

Subscribe: πŸ“‘ RSS | βš›οΈ Atom