Dynamic Object in GoloScript

Introduction

A Dynamic Object is a flexible data structure that allows you to add properties and methods on the fly, without defining a schema beforehand. It’s GoloScript’s equivalent to JavaScript objects or Python dictionaries with methods, but with an elegant syntax inspired by dynamic languages.

What is a Dynamic Object?

A Dynamic Object consists of two distinct elements:

  1. Properties: key-value pairs that store data
  2. Methods: named functions that define behaviors

Unlike classic objects in statically typed languages, you don’t need to define a class or structure in advance. The object can evolve dynamically during execution.

How Does a Dynamic Object Work?

Creation

To create a Dynamic Object, use the DynamicObject() function:

let obj = DynamicObject()

This creates an empty object, with no properties or methods.

Defining Properties

Properties are defined with the syntax : propertyName(value):

let person = DynamicObject()
    : name("Alice")
    : age(30)
    : city("Paris")

Mechanism: when you call : propertyName(value) with an argument, GoloScript:

Accessing Properties

To read a property, use the same syntax but without an argument:

println(person: name())      # Prints: Alice
println(person: age())       # Prints: 30

Mechanism: when you call : propertyName() without an argument, GoloScript:

Defining Methods

Methods are defined by assigning a lambda (anonymous function):

let person = DynamicObject()
    : name("Alice")
    : greet(|this| {
        println("Hello, my name is", this: name())
    })

Key points:

Calling Methods

To call a method, use the syntax : methodName() or : methodName(args...):

person: greet()              # Prints: Hello, my name is Alice

With arguments:

let calculator = DynamicObject()
    : add(|this, a, b| {
        return a + b
    })

let result = calculator: add(5, 3)  # result = 8

Method Chaining

One of the most powerful features of Dynamic Objects is method chaining:

let person = DynamicObject()
                : name("Alice")
                : age(30)
                : city("Paris")
                : greet(|this| {
                    println("I'm", this: name(), "from", this: city())
                })

person: greet()

Your methods can also return this to enable chaining:

let counter = DynamicObject()
    : value(0)
    : increment(|this| {
        this: value(this: value() + 1)
        return this
    })
    : decrement(|this| {
        this: value(this: value() - 1)
        return this
    })

counter: increment(): increment(): increment()  # value = 3
println(counter: value())  # Prints: 3

Introspection

GoloScript provides special methods to examine a Dynamic Object:

properties()

Returns an array containing the names of all properties:

let obj = DynamicObject()
    : id(1)
    : name("test")

println(obj: properties())  # Prints: [id, name]

methods()

Returns an array containing the names of all methods:

let obj = DynamicObject()
    : validate(|this| { return true })
    : save(|this| { println("Saving...") })

println(obj: methods())     # Prints: [validate, save]

⚠️ Note: The order of returned elements is not guaranteed (limitation of the underlying Go implementation).

define() Method

To explicitly define a property or method, you can use define(key, value):

let obj = DynamicObject()
obj: define("property", "value")
obj: define("method", |this| { println("Hello!") })

This method is useful when you want to define a key dynamically or avoid ambiguity.

JSON Serialization

Dynamic Objects can be serialized to JSON with the toJSON() function:

let person = DynamicObject()
    : name("Alice")
    : age(30)
    : greet(|this| { println("Hello") })

println(toJSON(person))  # {"name":"Alice","age":30}

Important: only properties are serialized. Methods are ignored during JSON conversion.

Use Cases

Dynamic Objects are particularly useful for:

  1. Dynamic configuration: create configuration objects that evolve
  2. Rapid prototyping: test ideas without defining rigid structures
  3. Data mapping: transform JSON data into manipulable objects
  4. Builder pattern: build complex objects with a fluent API
  5. Scripting: write flexible scripts that adapt to needs

Complete Example

# Create a person with properties and methods
let person = DynamicObject()
    : firstName("Alice")
    : lastName("Smith")
    : birthYear(1990)
    : fullName(|this| {
        return this: firstName() + " " + this: lastName()
    })
    : age(|this| {
        return 2024 - this: birthYear()
    })
    : greet(|this| {
        println("Hello! I'm", this: fullName())
        println("I'm", this: age(), "years old")
    })

# Use the object
person: greet()
# Prints:
# Hello! I'm Alice Smith
# I'm 34 years old

# Introspection
println("Available properties:", person: properties())
println("Available methods:", person: methods())

# Serialization
println("JSON:", toJSON(person))
# {"firstName":"Alice","lastName":"Smith","birthYear":1990}

© 2026 GoloScript Project | Built with Gu10berg

Subscribe: 📡 RSS | ⚛️ Atom