ddonche/goblin-lang
0.46.24
1
0
docs reference
[[collect]]

Collect


In Goblin, collect evaluates an expression repeatedly and returns the results as an array. It is useful whenever you need to generate a list of values, objects, strings, rolls, or function results.


Usage

What you write

numbers | collect 5 of roll 1d6
numbers | collect 5 of roll 1d6

What it does

Goblin evaluates the expression 5 times and places each result into an array.

Example result:

[4, 1, 6, 3, 2]
[4, 1, 6, 3, 2]

Each evaluation is independent.


Function Form

Collect can also be called like a normal function:

numbers | collect(5, roll 1d6)
numbers | collect(5, roll 1d6)

This is equivalent to:

numbers | collect 5 of roll 1d6
numbers | collect 5 of roll 1d6

Use whichever style is more readable in the surrounding code.


Common Examples

Random Numbers

rolls | collect 10 of roll 1d20
rolls | collect 10 of roll 1d20

Possible result:

[7, 14, 2, 19, 5, 11, 1, 20, 8, 4]
[7, 14, 2, 19, 5, 11, 1, 20, 8, 4]


Calling an Action

sentences | collect 5 of goblin_ipsum_sentence()
sentences | collect 5 of goblin_ipsum_sentence()

Produces:

[
    "Goblin words here.",
    "Another sentence here.",
    "More goblin words.",
    ...
]
[
    "Goblin words here.",
    "Another sentence here.",
    "More goblin words.",
    ...
]


Creating Objects

soldiers | collect 100 of Soldier()
soldiers | collect 100 of Soldier()

Produces an array containing 100 newly-created Soldier objects. Each object is independently constructed and fully initialized — collect does not copy, it evaluates fresh each time.


The Long Way

Before collect, the same operation required manually building the array.

sentences | []
repeat 5
    s | goblin_ipsum_sentence()
    put_last!(sentences, s)
xx
sentences | []
repeat 5
    s | goblin_ipsum_sentence()
    put_last!(sentences, s)
xx

This works perfectly fine.

However, the intent is:

Run this thing 5 times and collect the results.

So Goblin allows:

sentences | collect 5 of goblin_ipsum_sentence()
sentences | collect 5 of goblin_ipsum_sentence()

The loop still happens. Collect simply removes the plumbing.


How It Differs From Pack and Unpack

Collect and Pack are related but solve different problems.

Pack

Pack takes an array and collapses it into a single value.

digits | [1, 2, 3, 4, 5]
number | :pack(digits)
digits | [1, 2, 3, 4, 5]
number | :pack(digits)

Result:

12345

letters | ["g", "o", "b", "l", "i", "n"]
word | :pack(letters)
letters | ["g", "o", "b", "l", "i", "n"]
word | :pack(letters)

Result:

"goblin"

An array of digits becomes a number. An array of characters becomes a string.

Unpack

Unpack is the inverse — it splits a single value back into an array.

digits | :unpack(12345)    /// → [1, 2, 3, 4, 5]
chars  | :unpack("goblin") /// → ["g", "o", "b", "l", "i", "n"]
digits | :unpack(12345)    /// → [1, 2, 3, 4, 5]
chars  | :unpack("goblin") /// → ["g", "o", "b", "l", "i", "n"]

Collect

Collect generates new values by repeatedly evaluating an expression.

rolls | collect 5 of roll 1d6   /// → [4, 1, 6, 3, 2]
rolls | collect 5 of roll 1d6   /// → [4, 1, 6, 3, 2]

Rule of Thumb

If you need to collapse an array into one value — pack. If you need to split one value into an array — unpack. If you need to generate an array from scratch — collect.


Comparison With Other Languages

Python

sentences = []
for _ in range(5):
    sentences.append(goblin_ipsum_sentence())
sentences = []
for _ in range(5):
    sentences.append(goblin_ipsum_sentence())

More commonly:

sentences = [
    goblin_ipsum_sentence()
    for _ in range(5)
]
sentences = [
    goblin_ipsum_sentence()
    for _ in range(5)
]


JavaScript

const sentences =
    Array.from(
        { length: 5 },
        () => goblinIpsumSentence()
    );
const sentences =
    Array.from(
        { length: 5 },
        () => goblinIpsumSentence()
    );


Ruby

sentences =
    5.times.map do
        goblin_ipsum_sentence()
    end
sentences =
    5.times.map do
        goblin_ipsum_sentence()
    end


Goblin

sentences | collect 5 of goblin_ipsum_sentence()
sentences | collect 5 of goblin_ipsum_sentence()

Goblin names the operation directly. You are collecting results from repeated evaluation.


Why This Exists

Building arrays by repeatedly evaluating something is an extremely common operation. Without collect, every use requires creating an empty array, running a loop, generating a value, appending it, and returning the array.

Collect expresses the intent directly:

Evaluate this N times and give me the results.

The underlying loop still exists, but the programmer no longer has to write it.